pcre-8.31/0000755000222100022210000000000011775533032007371 500000000000000pcre-8.31/doc/0000755000222100022210000000000011775533032010136 500000000000000pcre-8.31/doc/html/0000755000222100022210000000000011775533031011101 500000000000000pcre-8.31/doc/html/pcre16.html0000644000222100022210000003677511775533017013035 00000000000000 pcre16 specification

pcre16 man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

#include <pcre.h>


PCRE 16-BIT API BASIC FUNCTIONS

pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr);

pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr);

pcre16_extra *pcre16_study(const pcre16 *code, int options, const char **errptr);

void pcre16_free_study(pcre16_extra *extra);

int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, PCRE_SPTR16 subject, int length, int startoffset, int options, int *ovector, int ovecsize);

int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, PCRE_SPTR16 subject, int length, int startoffset, int options, int *ovector, int ovecsize, int *workspace, int wscount);


PCRE 16-BIT API STRING EXTRACTION FUNCTIONS

int pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_UCHAR16 *buffer, int buffersize);

int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, int buffersize);

int pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_SPTR16 *stringptr);

int pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 name);

int pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last);

int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_SPTR16 *stringptr);

int pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 **listptr);

void pcre16_free_substring(PCRE_SPTR16 stringptr);

void pcre16_free_substring_list(PCRE_SPTR16 *stringptr);


PCRE 16-BIT API AUXILIARY FUNCTIONS

pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize);

void pcre16_jit_stack_free(pcre16_jit_stack *stack);

void pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *data);

const unsigned char *pcre16_maketables(void);

int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, int what, void *where);

int pcre16_refcount(pcre16 *code, int adjust);

int pcre16_config(int what, void *where);

const char *pcre16_version(void);

int pcre16_pattern_to_host_byte_order(pcre16 *code, pcre16_extra *extra, const unsigned char *tables);


PCRE 16-BIT API INDIRECTED FUNCTIONS

void *(*pcre16_malloc)(size_t);

void (*pcre16_free)(void *);

void *(*pcre16_stack_malloc)(size_t);

void (*pcre16_stack_free)(void *);

int (*pcre16_callout)(pcre16_callout_block *);


PCRE 16-BIT API 16-BIT-ONLY FUNCTION

int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input, int length, int *byte_order, int keep_boms);


THE PCRE 16-BIT LIBRARY

Starting with release 8.30, it is possible to compile a PCRE library that supports 16-bit character strings, including UTF-16 strings, as well as or instead of the original 8-bit library. The majority of the work to make this possible was done by Zoltan Herczeg. The two libraries contain identical sets of functions, used in exactly the same way. Only the names of the functions and the data types of their arguments and results are different. To avoid over-complication and reduce the documentation maintenance load, most of the PCRE documentation describes the 8-bit library, with only occasional references to the 16-bit library. This page describes what is different when you use the 16-bit library.

WARNING: A single application can be linked with both libraries, but you must take care when processing any particular pattern to use functions from just one library. For example, if you want to study a pattern that was compiled with pcre16_compile(), you must do so with pcre16_study(), not pcre_study(), and you must free the study data with pcre16_free_study().


THE HEADER FILE

There is only one header file, pcre.h. It contains prototypes for all the functions in both libraries, as well as definitions of flags, structures, error codes, etc.


THE LIBRARY NAME

In Unix-like systems, the 16-bit library is called libpcre16, and can normally be accesss by adding -lpcre16 to the command for linking an application that uses PCRE.


STRING TYPES

In the 8-bit library, strings are passed to PCRE library functions as vectors of bytes with the C type "char *". In the 16-bit library, strings are passed as vectors of unsigned 16-bit quantities. The macro PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is defined as "const PCRE_UCHAR16 *". In very many environments, "short int" is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16 as "short int", but checks that it really is a 16-bit data type. If it is not, the build fails with an error message telling the maintainer to modify the definition appropriately.


STRUCTURE TYPES

The types of the opaque structures that are used for compiled 16-bit patterns and JIT stacks are pcre16 and pcre16_jit_stack respectively. The type of the user-accessible structure that is returned by pcre16_study() is pcre16_extra, and the type of the structure that is used for passing data to a callout function is pcre16_callout_block. These structures contain the same fields, with the same names, as their 8-bit counterparts. The only difference is that pointers to character strings are 16-bit instead of 8-bit types.


16-BIT FUNCTIONS

For every function in the 8-bit library there is a corresponding function in the 16-bit library with a name that starts with pcre16_ instead of pcre_. The prototypes are listed above. In addition, there is one extra function, pcre16_utf16_to_host_byte_order(). This is a utility function that converts a UTF-16 character string to host byte order if necessary. The other 16-bit functions expect the strings they are passed to be in host byte order.

The input and output arguments of pcre16_utf16_to_host_byte_order() may point to the same address, that is, conversion in place is supported. The output buffer must be at least as long as the input.

The length argument specifies the number of 16-bit data units in the input string; a negative value specifies a zero-terminated string.

If byte_order is NULL, it is assumed that the string starts off in host byte order. This may be changed by byte-order marks (BOMs) anywhere in the string (commonly as the first character).

If byte_order is not NULL, a non-zero value of the integer to which it points means that the input starts off in host byte order, otherwise the opposite order is assumed. Again, BOMs in the string can change this. The final byte order is passed back at the end of processing.

If keep_boms is not zero, byte-order mark characters (0xfeff) are copied into the output string. Otherwise they are discarded.

The result of the function is the number of 16-bit units placed into the output buffer, including the zero terminator if the string was zero-terminated.


SUBJECT STRING OFFSETS

The offsets within subject strings that are returned by the matching functions are in 16-bit units rather than bytes.


NAMED SUBPATTERNS

The name-to-number translation table that is maintained for named subpatterns uses 16-bit characters. The pcre16_get_stringtable_entries() function returns the length of each entry in the table as the number of 16-bit data units.


OPTION NAMES

There are two new general option names, PCRE_UTF16 and PCRE_NO_UTF16_CHECK, which correspond to PCRE_UTF8 and PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options define the same bits in the options word. There is a discussion about the validity of UTF-16 strings in the pcreunicode page.

For the pcre16_config() function there is an option PCRE_CONFIG_UTF16 that returns 1 if UTF-16 support is configured, otherwise 0. If this option is given to pcre_config(), or if the PCRE_CONFIG_UTF8 option is given to pcre16_config(), the result is the PCRE_ERROR_BADOPTION error.


CHARACTER CODES

In 16-bit mode, when PCRE_UTF16 is not set, character values are treated in the same way as in 8-bit, non UTF-8 mode, except, of course, that they can range from 0 to 0xffff instead of 0 to 0xff. Character types for characters less than 0xff can therefore be influenced by the locale in the same way as before. Characters greater than 0xff have only one case, and no "type" (such as letter or digit).

In UTF-16 mode, the character code is Unicode, in the range 0 to 0x10ffff, with the exception of values in the range 0xd800 to 0xdfff because those are "surrogate" values that are used in pairs to encode values greater than 0xffff.

A UTF-16 string can indicate its endianness by special code knows as a byte-order mark (BOM). The PCRE functions do not handle this, expecting strings to be in host byte order. A utility function called pcre16_utf16_to_host_byte_order() is provided to help with this (see above).


ERROR NAMES

The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 correspond to their 8-bit counterparts. The error PCRE_ERROR_BADMODE is given when a compiled pattern is passed to a function that processes patterns in the other mode, for example, if a pattern compiled with pcre_compile() is passed to pcre16_exec().

There are new error codes whose names begin with PCRE_UTF16_ERR for invalid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for UTF-8 strings that are described in the section entitled "Reason codes for invalid UTF-8 strings" in the main pcreapi page. The UTF-16 errors are:

  PCRE_UTF16_ERR1  Missing low surrogate at end of string
  PCRE_UTF16_ERR2  Invalid low surrogate follows high surrogate
  PCRE_UTF16_ERR3  Isolated low surrogate
  PCRE_UTF16_ERR4  Invalid character 0xfffe


ERROR TEXTS

If there is an error while compiling a pattern, the error text that is passed back by pcre16_compile() or pcre16_compile2() is still an 8-bit character string, zero-terminated.


CALLOUTS

The subject and mark fields in the callout block that is passed to a callout function point to 16-bit vectors.


TESTING

The pcretest program continues to operate with 8-bit input and output files, but it can be used for testing the 16-bit library. If it is run with the command line option -16, patterns and subject strings are converted from 8-bit to 16-bit before being passed to PCRE, and the 16-bit library functions are used instead of the 8-bit ones. Returned 16-bit strings are converted to 8-bit for output. If the 8-bit library was not compiled, pcretest defaults to 16-bit and the -16 option is ignored.

When PCRE is being built, the RunTest script that is called by "make check" uses the pcretest -C option to discover which of the 8-bit and 16-bit libraries has been built, and runs the tests appropriately.


NOT SUPPORTED IN 16-BIT MODE

Not all the features of the 8-bit library are available with the 16-bit library. The C++ and POSIX wrapper functions support only the 8-bit library, and the pcregrep program is at present 8-bit only.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 14 April 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_assign_jit_stack.html0000644000222100022210000000450711775533017016251 00000000000000 pcre_assign_jit_stack specification

pcre_assign_jit_stack man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

void pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *data);

void pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *data);


DESCRIPTION

This function provides control over the memory used as a stack at run-time by a call to pcre[16]_exec() with a pattern that has been successfully compiled with JIT optimization. The arguments are:

  extra     the data pointer returned by pcre[16]_study()
  callback  a callback function
  data      a JIT stack or a value to be passed to the callback
              function

If callback is NULL and data is NULL, an internal 32K block on the machine stack is used.

If callback is NULL and data is not NULL, data must be a valid JIT stack, the result of calling pcre[16]_jit_stack_alloc().

If callback not NULL, it is called with data as an argument at the start of matching, in order to set up a JIT stack. If the result is NULL, the internal 32K stack is used; otherwise the return value must be a valid JIT stack, the result of calling pcre[16]_jit_stack_alloc().

You may safely assign the same JIT stack to multiple patterns, as long as they are all matched in the same thread. In a multithread application, each thread must use its own JIT stack. For more details, see the pcrejit page.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre.html0000644000222100022210000001607111775533017012651 00000000000000 pcre specification

pcre man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


INTRODUCTION

The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl, with just a few differences. Some features that appeared in Python and PCRE before they appeared in Perl are also available using the Python syntax, there is some support for one or two .NET and Oniguruma syntax items, and there is an option for requesting some minor changes that give better JavaScript compatibility.

Starting with release 8.30, it is possible to compile two separate PCRE libraries: the original, which supports 8-bit character strings (including UTF-8 strings), and a second library that supports 16-bit character strings (including UTF-16 strings). The build process allows either one or both to be built. The majority of the work to make this possible was done by Zoltan Herczeg.

The two libraries contain identical sets of functions, except that the names in the 16-bit library start with pcre16_ instead of pcre_. To avoid over-complication and reduce the documentation maintenance load, most of the documentation describes the 8-bit library, with the differences for the 16-bit library described separately in the pcre16 page. References to functions or structures of the form pcre[16]_xxx should be read as meaning "pcre_xxx when using the 8-bit library and pcre16_xxx when using the 16-bit library".

The current implementation of PCRE corresponds approximately with Perl 5.12, including support for UTF-8/16 encoded strings and Unicode general category properties. However, UTF-8/16 and Unicode support has to be explicitly enabled; it is not the default. The Unicode tables correspond to Unicode release 6.0.0.

In addition to the Perl-compatible matching function, PCRE contains an alternative function that matches the same compiled patterns in a different way. In certain circumstances, the alternative function has some advantages. For a discussion of the two matching algorithms, see the pcrematching page.

PCRE is written in C and released as a C library. A number of people have written wrappers and interfaces of various kinds. In particular, Google Inc. have provided a comprehensive C++ wrapper for the 8-bit library. This is now included as part of the PCRE distribution. The pcrecpp page has details of this interface. Other people's contributions can be found in the Contrib directory at the primary FTP site, which is: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre

Details of exactly which Perl regular expression features are and are not supported by PCRE are given in separate documents. See the pcrepattern and pcrecompat pages. There is a syntax summary in the pcresyntax page.

Some features of PCRE can be included, excluded, or changed when the library is built. The pcre_config() function makes it possible for a client to discover which features are available. The features themselves are described in the pcrebuild page. Documentation about building PCRE for various operating systems can be found in the README and NON-UNIX-USE files in the source distribution.

The libraries contains a number of undocumented internal functions and data tables that are used by more than one of the exported external functions, but which are not intended for use by external callers. Their names all begin with "_pcre_" or "_pcre16_", which hopefully will not provoke any name clashes. In some environments, it is possible to control which external symbols are exported when a shared library is built, and in these cases the undocumented symbols are not exported.


USER DOCUMENTATION

The user documentation for PCRE comprises a number of different sections. In the "man" format, each of these is a separate "man page". In the HTML format, each is a separate page, linked from the index page. In the plain text format, all the sections, except the pcredemo section, are concatenated, for ease of searching. The sections are as follows:

  pcre              this document
  pcre16            details of the 16-bit library
  pcre-config       show PCRE installation configuration information
  pcreapi           details of PCRE's native C API
  pcrebuild         options for building PCRE
  pcrecallout       details of the callout feature
  pcrecompat        discussion of Perl compatibility
  pcrecpp           details of the C++ wrapper for the 8-bit library
  pcredemo          a demonstration C program that uses PCRE
  pcregrep          description of the pcregrep command (8-bit only)
  pcrejit           discussion of the just-in-time optimization support
  pcrelimits        details of size and other limits
  pcrematching      discussion of the two matching algorithms
  pcrepartial       details of the partial matching facility
  pcrepattern       syntax and semantics of supported regular expressions
  pcreperform       discussion of performance issues
  pcreposix         the POSIX-compatible C API for the 8-bit library
  pcreprecompile    details of saving and re-using precompiled patterns
  pcresample        discussion of the pcredemo program
  pcrestack         discussion of stack usage
  pcresyntax        quick syntax reference
  pcretest          description of the pcretest testing command
  pcreunicode       discussion of Unicode and UTF-8/16 support
In addition, in the "man" and HTML formats, there is a short page for each 8-bit C library function, listing its arguments and results.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.

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 two initials, followed by the two digits 10, at the domain cam.ac.uk.


REVISION

Last updated: 10 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcreperform.html0000644000222100022210000001727111775533020014241 00000000000000 pcreperform specification

pcreperform man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

PCRE PERFORMANCE

Two aspects of performance are discussed below: memory usage and processing time. The way you express your pattern as a regular expression can affect both of them.


COMPILED PATTERN MEMORY USAGE

Patterns are compiled by PCRE into a reasonably efficient interpretive code, so that most simple patterns do not use much memory. However, there is one case where the memory usage of a compiled pattern can be unexpectedly large. If a parenthesized subpattern has a quantifier with a minimum greater than 1 and/or a limited maximum, the whole subpattern is repeated in the compiled code. For example, the pattern

  (abc|def){2,4}
is compiled as if it were
  (abc|def)(abc|def)((abc|def)(abc|def)?)?
(Technical aside: It is done this way so that backtrack points within each of the repetitions can be independently maintained.)

For regular expressions whose quantifiers use only small numbers, this is not usually a problem. However, if the numbers are large, and particularly if such repetitions are nested, the memory usage can become an embarrassment. For example, the very simple pattern

  ((ab){1,1000}c){1,3}
uses 51K bytes when compiled using the 8-bit library. When PCRE is compiled with its default internal pointer size of two bytes, the size limit on a compiled pattern is 64K data units, and this is reached with the above pattern if the outer repetition is increased from 3 to 4. PCRE can be compiled to use larger internal pointers and thus handle larger compiled patterns, but it is better to try to rewrite your pattern to use less memory if you can.

One way of reducing the memory usage for such patterns is to make use of PCRE's "subroutine" facility. Re-writing the above pattern as

  ((ab)(?2){0,999}c)(?1){0,2}
reduces the memory requirements to 18K, and indeed it remains under 20K even with the outer repetition increased to 100. However, this pattern is not exactly equivalent, because the "subroutine" calls are treated as atomic groups into which there can be no backtracking if there is a subsequent matching failure. Therefore, PCRE cannot do this kind of rewriting automatically. Furthermore, there is a noticeable loss of speed when executing the modified pattern. Nevertheless, if the atomic grouping is not a problem and the loss of speed is acceptable, this kind of rewriting will allow you to process patterns that PCRE cannot otherwise handle.


STACK USAGE AT RUN TIME

When pcre_exec() or pcre16_exec() is used for matching, certain kinds of pattern can cause it to use large amounts of the process stack. In some environments the default process stack is quite small, and if it runs out the result is often SIGSEGV. This issue is probably the most frequently raised problem with PCRE. Rewriting your pattern can often help. The pcrestack documentation discusses this issue in detail.


PROCESSING TIME

Certain items in regular expression patterns are processed more efficiently than others. It is more efficient to use a character class like [aeiou] than a set of single-character alternatives such as (a|e|i|o|u). In general, the simplest construction that provides the required behaviour is usually the most efficient. Jeffrey Friedl's book contains a lot of useful general discussion about optimizing regular expressions for efficient performance. This document contains a few observations about PCRE.

Using Unicode character properties (the \p, \P, and \X escapes) is slow, because PCRE has to scan a structure that contains data for over fifteen thousand characters whenever it needs a character's property. If you can find an alternative pattern that does not use character properties, it will probably be faster.

By default, the escape sequences \b, \d, \s, and \w, and the POSIX character classes such as [:alpha:] do not use Unicode properties, partly for backwards compatibility, and partly for performance reasons. However, you can set PCRE_UCP if you want Unicode character properties to be used. This can double the matching time for items such as \d, when matched with a traditional matching function; the performance loss is less with a DFA matching function, and in both cases there is not much difference for \b.

When a pattern begins with .* not in parentheses, or in parentheses that are not the subject of a backreference, and the PCRE_DOTALL option is set, the pattern is implicitly anchored by PCRE, since it can match only at the start of a subject string. However, if PCRE_DOTALL is not set, PCRE cannot make this optimization, because the . metacharacter does not then match a newline, and if the subject string contains newlines, the pattern may match from the character immediately following one of them instead of from the very start. For example, the pattern

  .*second
matches the subject "first\nand second" (where \n stands for a newline character), with the match starting at the seventh character. In order to do this, PCRE has to retry the match starting after every newline in the subject.

If you are using such a pattern with subject strings that do not contain newlines, the best performance is obtained by setting PCRE_DOTALL, or starting the pattern with ^.* or ^.*? to indicate explicit anchoring. That saves PCRE from having to scan along the subject looking for a newline to restart at.

Beware of patterns that contain nested indefinite repeats. These can take a long time to run when applied to a string that does not match. Consider the pattern fragment

  ^(a+)*
This can match "aaaa" in 16 different ways, and this number increases very rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4 times, and for each of those cases other than 0 or 4, the + repeats can match different numbers of times.) When the remainder of the pattern is such that the entire match is going to fail, PCRE has in principle to try every possible variation, and this can take an extremely long time, even for relatively short strings.

An optimization catches some of the more simple cases such as

  (a+)*b
where a literal character follows. Before embarking on the standard matching procedure, PCRE checks that there is a "b" later in the subject string, and if there is not, it fails the match immediately. However, when there is no following literal this optimization cannot be used. You can see the difference by comparing the behaviour of
  (a+)*\d
with the pattern above. The former gives a failure almost instantly when applied to a whole line of "a" characters, whereas the latter takes an appreciable time with strings longer than about 20 characters.

In many cases, the solution to this kind of performance issue is to use an atomic group or a possessive quantifier.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 09 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrepartial.html0000644000222100022210000005221011775533020014213 00000000000000 pcrepartial specification

pcrepartial man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


PARTIAL MATCHING IN PCRE

In normal use of PCRE, if the subject string that is passed to a matching function matches as far as it goes, but is too short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances where it might be helpful to distinguish this case from other cases in which there is no match.

Consider, for example, an application where a human is required to type in data for a field with specific formatting requirements. An example might be a date in the form ddmmmyy, defined by this pattern:

  ^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$
If the application sees the user's keystrokes one by one, and can check that what has been typed so far is potentially valid, it is able to raise an error as soon as a mistake is made, by beeping and not reflecting the character that has been typed, for example. This immediate feedback is likely to be a better user interface than a check that is delayed until the entire string has been entered. Partial matching can also be useful when the subject string is very long and is not all available at once.

PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and PCRE_PARTIAL_HARD options, which can be set when calling any of the matching functions. For backwards compatibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. The essential difference between the two options is whether or not a partial match is preferred to an alternative complete match, though the details differ between the two types of matching function. If both options are set, PCRE_PARTIAL_HARD takes precedence.

If you want to use partial matching with just-in-time optimized code, you must call pcre_study() or pcre16_study() with one or both of these options:

  PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
  PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non-partial matches on the same pattern. If the appropriate JIT study mode has not been set for a match, the interpretive matching code is used.

Setting a partial matching option disables two of PCRE's standard optimizations. PCRE remembers the last literal data unit in a pattern, and abandons matching immediately if it is not present in the subject string. This optimization cannot be used for a subject string that might match only partially. If the pattern was studied, PCRE knows the minimum length of a matching string, and does not bother to run the matching function on shorter strings. This optimization is also disabled for partial matching.


PARTIAL MATCHING USING pcre_exec() OR pcre16_exec()

A partial match occurs during a call to pcre_exec() or pcre16_exec() when the end of the subject string is reached successfully, but matching cannot continue because more characters are needed. However, at least one character in the subject must have been inspected. This character need not form part of the final matched string; lookbehind assertions and the \K escape sequence provide ways of inspecting characters before the start of a matched substring. The requirement for inspecting at least one character exists because an empty string can always be matched; without such a restriction there would always be a partial match of an empty string at the end of the subject.

If there are at least two slots in the offsets vector when a partial match is returned, the first slot is set to the offset of the earliest character that was inspected. For convenience, the second offset points to the end of the subject so that a substring can easily be identified.

For the majority of patterns, the first offset identifies the start of the partially matched string. However, for patterns that contain lookbehind assertions, or \K, or begin with \b or \B, earlier characters have been inspected while carrying out the match. For example:

  /(?<=abc)123/
This pattern matches "123", but only if it is preceded by "abc". If the subject string is "xyzabc12", the offsets after a partial match are for the substring "abc12", because all these characters are needed if another match is tried with extra characters added to the subject.

What happens when a partial match is identified depends on which of the two partial matching options are set.


PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec()

If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre16_exec() identifies a partial match, the partial match is remembered, but matching continues as normal, and other alternatives in the pattern are tried. If no complete match can be found, PCRE_ERROR_PARTIAL is returned instead of PCRE_ERROR_NOMATCH.

This option is "soft" because it prefers a complete match over a partial match. All the various matching items in a pattern behave as if the subject string is potentially complete. For example, \z, \Z, and $ match at the end of the subject, as normal, and for \b and \B the end of the subject is treated as a non-alphanumeric.

If there is more than one partial match, the first one that was found provides the data that is returned. Consider this pattern:

  /123\w+X|dogY/
If this is matched against the subject string "abc123dog", both alternatives fail to match, but the end of the subject is reached during matching, so PCRE_ERROR_PARTIAL is returned. The offsets are set to 3 and 9, identifying "123dog" as the first partial match that was found. (In this example, there are two partial matches, because "dog" on its own partially matches the second alternative.)


PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec()

If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre16_exec(), PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, without continuing to search for possible complete matches. This option is "hard" because it prefers an earlier partial match over a later complete match. For this reason, the assumption is made that the end of the supplied subject string may not be the true end of the available data, and so, if \z, \Z, \b, \B, or $ are encountered at the end of the subject, the result is PCRE_ERROR_PARTIAL, provided that at least one character in the subject has been inspected.

Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 subject strings are checked for validity. Normally, an invalid sequence causes the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the special case of a truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when PCRE_PARTIAL_HARD is set.


Comparing hard and soft partial matching

The difference between the two partial matching options can be illustrated by a pattern such as:

  /dog(sbody)?/
This matches either "dog" or "dogsbody", greedily (that is, it prefers the longer string if possible). If it is matched against the string "dog" with PCRE_PARTIAL_SOFT, it yields a complete match for "dog". However, if PCRE_PARTIAL_HARD is set, the result is PCRE_ERROR_PARTIAL. On the other hand, if the pattern is made ungreedy the result is different:
  /dog(sbody)??/
In this case the result is always a complete match because that is found first, and matching never continues after finding a complete match. It might be easier to follow this explanation by thinking of the two patterns like this:
  /dog(sbody)?/    is the same as  /dogsbody|dog/
  /dog(sbody)??/   is the same as  /dog|dogsbody/
The second pattern will never match "dogsbody", because it will always find the shorter match first.


PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec()

The DFA functions move along the subject string character by character, without backtracking, searching for all possible matches simultaneously. If the end of the subject is reached before the end of the pattern, there is the possibility of a partial match, again provided that at least one character has been inspected.

When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there have been no complete matches. Otherwise, the complete matches are returned. However, if PCRE_PARTIAL_HARD is set, a partial match takes precedence over any complete matches. The portion of the string that was inspected when the longest partial match was found is set as the first matching string, provided there are at least two slots in the offsets vector.

Because the DFA functions always search for all possible matches, and there is no difference between greedy and ungreedy repetition, their behaviour is different from the standard functions when PCRE_PARTIAL_HARD is set. Consider the string "dog" matched against the ungreedy pattern shown above:

  /dog(sbody)??/
Whereas the standard functions stop as soon as they find the complete match for "dog", the DFA functions also find the partial match for "dogsbody", and so return that when PCRE_PARTIAL_HARD is set.


PARTIAL MATCHING AND WORD BOUNDARIES

If a pattern ends with one of sequences \b or \B, which test for word boundaries, partial matching with PCRE_PARTIAL_SOFT can give counter-intuitive results. Consider this pattern:

  /\bcat\b/
This matches "cat", provided there is a word boundary at either end. If the subject string is "the cat", the comparison of the final "t" with a following character cannot take place, so a partial match is found. However, normal matching carries on, and \b matches at the end of the subject when the last character is a letter, so a complete match is found. The result, therefore, is not PCRE_ERROR_PARTIAL. Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because then the partial match takes precedence.


FORMERLY RESTRICTED PATTERNS

For releases of PCRE prior to 8.00, because of the way certain internal optimizations were implemented in the pcre_exec() function, the PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be used with all patterns. From release 8.00 onwards, the restrictions no longer apply, and partial matching with can be requested for any pattern.

Items that were formerly restricted were repeated single characters and repeated metasequences. If PCRE_PARTIAL was set for a pattern that did not conform to the restrictions, pcre_exec() returned the error code PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled pattern can be used for partial matching now always returns 1.


EXAMPLE OF PARTIAL MATCHING USING PCRETEST

If the escape sequence \P is present in a pcretest data line, the PCRE_PARTIAL_SOFT option is used for the match. Here is a run of pcretest that uses the date example quoted above:

    re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
  data> 25jun04\P
   0: 25jun04
   1: jun
  data> 25dec3\P
  Partial match: 23dec3
  data> 3ju\P
  Partial match: 3ju
  data> 3juj\P
  No match
  data> j\P
  No match
The first data string is matched completely, so pcretest shows the matched substrings. The remaining four strings do not match the complete pattern, but the first two are partial matches. Similar output is obtained if DFA matching is used.

If the escape sequence \P is present more than once in a pcretest data line, the PCRE_PARTIAL_HARD option is set for the match.


MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec()

When a partial match has been found using a DFA matching function, it is possible to continue the match by providing additional subject data and calling the function again with the same compiled regular expression, this time setting the PCRE_DFA_RESTART option. You must pass the same working space as before, because this is where details of the previous partial match are stored. Here is an example using pcretest, using the \R escape sequence to set the PCRE_DFA_RESTART option (\D specifies the use of the DFA matching function):

    re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
  data> 23ja\P\D
  Partial match: 23ja
  data> n05\R\D
   0: n05
The first call has "23ja" as the subject, and requests partial matching; the second call has "n05" as the subject for the continued (restarted) match. Notice that when the match is complete, only the last part is shown; PCRE does not retain the previously partially-matched string. It is up to the calling program to do that if it needs to.

You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with PCRE_DFA_RESTART to continue partial matching over multiple segments. This facility can be used to pass very long subject strings to the DFA matching functions.


MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec()

From release 8.00, the standard matching functions can also be used to do multi-segment matching. Unlike the DFA functions, it is not possible to restart the previous match with a new segment of data. Instead, new data must be added to the previous subject string, and the entire match re-run, starting from the point where the partial match occurred. Earlier data can be discarded.

It is best to use PCRE_PARTIAL_HARD in this situation, because it does not treat the end of a segment as the end of the subject when matching \z, \Z, \b, \B, and $. Consider an unanchored pattern that matches dates:

    re> /\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d/
  data> The date is 23ja\P\P
  Partial match: 23ja
At this stage, an application could discard the text preceding "23ja", add on text from the next segment, and call the matching function again. Unlike the DFA matching functions, the entire matching string must always be available, and the complete matching process occurs for each call, so more memory and more processing time is needed.

Note: If the pattern contains lookbehind assertions, or \K, or starts with \b or \B, the string that is returned for a partial match includes characters that precede the partially matched string itself, because these must be retained when adding on more characters for a subsequent matching attempt. However, in some cases you may need to retain even earlier characters, as discussed in the next section.


ISSUES WITH MULTI-SEGMENT MATCHING

Certain types of pattern may give problems with multi-segment matching, whichever matching function is used.

1. If the pattern contains a test for the beginning of a line, you need to pass the PCRE_NOTBOL option when the subject string for any call does start at the beginning of a line. There is also a PCRE_NOTEOL option, but in practice when doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL.

2. Lookbehind assertions that have already been obeyed are catered for in the offsets that are returned for a partial match. However a lookbehind assertion later in the pattern could require even earlier characters to be inspected. You can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the pcre_fullinfo() or pcre16_fullinfo() functions to obtain the length of the largest lookbehind in the pattern. This length is given in characters, not bytes. If you always retain at least that many characters before the partially matched string, all should be well. (Of course, near the start of the subject, fewer characters may be present; in that case all characters should be retained.)

3. Because a partial match must always contain at least one character, what might be considered a partial match of an empty string actually gives a "no match" result. For example:

    re> /c(?<=abc)x/
  data> ab\P
  No match
If the next segment begins "cx", a match should be found, but this will only happen if characters from the previous segment are retained. For this reason, a "no match" result should be interpreted as "partial match of an empty string" when the pattern contains lookbehinds.

4. Matching a subject string that is split into multiple segments may not always produce exactly the same result as matching over one single long string, especially when PCRE_PARTIAL_SOFT is used. The section "Partial Matching and Word Boundaries" above describes an issue that arises if the pattern ends with \b or \B. Another kind of difference may occur when there are multiple matching possibilities, because (for PCRE_PARTIAL_SOFT) a partial match result is given only when there are no completed matches. This means that as soon as the shortest match has been found, continuation to a new subject segment is no longer possible. Consider again this pcretest example:

    re> /dog(sbody)?/
  data> dogsb\P
   0: dog
  data> do\P\D
  Partial match: do
  data> gsb\R\P\D
   0: g
  data> dogsbody\D
   0: dogsbody
   1: dog
The first data line passes the string "dogsb" to a standard matching function, setting the PCRE_PARTIAL_SOFT option. Although the string is a partial match for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter string "dog" is a complete match. Similarly, when the subject is presented to a DFA matching function in several parts ("do" and "gsb" being the first two) the match stops when "dog" has been found, and it is not possible to continue. On the other hand, if "dogsbody" is presented as a single string, a DFA matching function finds both matches.

Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching multi-segment data. The example above then behaves differently:

    re> /dog(sbody)?/
  data> dogsb\P\P
  Partial match: dogsb
  data> do\P\D
  Partial match: do
  data> gsb\R\P\P\D
  Partial match: gsb
5. Patterns that contain alternatives at the top level which do not all start with the same pattern item may not work as expected when PCRE_DFA_RESTART is used. For example, consider this pattern:
  1234|3789
If the first part of the subject is "ABC123", a partial match of the first alternative is found at offset 3. There is no partial match for the second alternative, because such a match does not start at the same point in the subject string. Attempting to continue with the string "7890" does not yield a match because only those alternatives that match at one point in the subject are remembered. The problem arises because the start of the second alternative matches within the first alternative. There is no problem with anchored patterns or patterns such as:
  1234|ABCD
where no string can be a partial match for both alternatives. This is not a problem if a standard matching function is used, because the entire match has to be rerun each time:
    re> /1234|3789/
  data> ABC123\P\P
  Partial match: 123
  data> 1237890
   0: 3789
Of course, instead of using PCRE_DFA_RESTART, the same technique of re-running the entire match can also be used with the DFA matching functions. Another possibility is to work with two buffers. If a partial match at offset n in the first buffer is followed by "no match" when PCRE_DFA_RESTART is used on the second buffer, you can then try a new match starting at offset n+1 in the first buffer.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 24 February 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcreunicode.html0000644000222100022210000002425411775533020014214 00000000000000 pcreunicode specification

pcreunicode man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT

From Release 8.30, in addition to its previous UTF-8 support, PCRE also supports UTF-16 by means of a separate 16-bit library. This can be built as well as, or instead of, the 8-bit library.


UTF-8 SUPPORT

In order process UTF-8 strings, you must build PCRE's 8-bit library with UTF support, and, in addition, you must call pcre_compile() with the PCRE_UTF8 option flag, or the pattern must start with the sequence (*UTF8). When either of these is the case, both the pattern and any subject strings that are matched against it are treated as UTF-8 strings instead of strings of 1-byte characters.


UTF-16 SUPPORT

In order process UTF-16 strings, you must build PCRE's 16-bit library with UTF support, and, in addition, you must call pcre16_compile() with the PCRE_UTF16 option flag, or the pattern must start with the sequence (*UTF16). When either of these is the case, both the pattern and any subject strings that are matched against it are treated as UTF-16 strings instead of strings of 16-bit characters.


UTF SUPPORT OVERHEAD

If you compile PCRE with UTF support, but do not use it at run time, the library will be a bit bigger, but the additional run time overhead is limited to testing the PCRE_UTF8/16 flag occasionally, so should not be very big.


UNICODE PROPERTY SUPPORT

If PCRE is built with Unicode character property support (which implies UTF support), the escape sequences \p{..}, \P{..}, and \X can be used. The available properties that can be tested are limited to the general category properties such as Lu for an upper case letter or Nd for a decimal number, the Unicode script names such as Arabic or Han, and the derived properties Any and L&. A full list is given in the pcrepattern documentation. Only the short names for properties are supported. For example, \p{L} matches a letter. Its Perl synonym, \p{Letter}, is not supported. Furthermore, in Perl, many properties may optionally be prefixed by "Is", for compatibility with Perl 5.6. PCRE does not support this.


Validity of UTF-8 strings

When you set the PCRE_UTF8 flag, the byte strings passed as patterns and subjects are (by default) checked for validity on entry to the relevant functions. The entire string is checked before any other processing takes place. From release 7.3 of PCRE, the check is according the rules of RFC 3629, which are themselves derived from the Unicode specification. Earlier releases of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0 to U+10FFFF, excluding U+D800 to U+DFFF.

The excluded code points are the "Surrogate Area" of Unicode. They are reserved for use by UTF-16, where they are used in pairs to encode codepoints with values greater than 0xFFFF. The code points that are encoded by UTF-16 pairs are available independently in the UTF-8 encoding. (In other words, the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8.)

If an invalid UTF-8 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first byte of the failing character. The run-time functions pcre_exec() and pcre_dfa_exec() also pass back this information, as well as a more detailed reason code if the caller has provided memory in which to do this.

In some situations, you may already know that your strings are valid, and therefore want to skip these checks in order to improve performance, for example in the case of a long subject string that is being scanned repeatedly with different patterns. If you set the PCRE_NO_UTF8_CHECK flag at compile time or at run time, PCRE assumes that the pattern or subject it is given (respectively) contains only valid UTF-8 codes. In this case, it does not diagnose an invalid UTF-8 string.

If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what happens depends on why the string is invalid. If the string conforms to the "old" definition of UTF-8 (RFC 2279), it is processed as a string of characters in the range 0 to 0x7FFFFFFF by pcre_dfa_exec() and the interpreted version of pcre_exec(). In other words, apart from the initial validity test, these functions (when in UTF-8 mode) handle strings according to the more liberal rules of RFC 2279. However, the just-in-time (JIT) optimization for pcre_exec() supports only RFC 3629. If you are using JIT optimization, or if the string does not even conform to RFC 2279, the result is undefined. Your program may crash.

If you want to process strings of values in the full range 0 to 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this situation, you will have to apply your own validity check, and avoid the use of JIT optimization.


Validity of UTF-16 strings

When you set the PCRE_UTF16 flag, the strings of 16-bit data units that are passed as patterns and subjects are (by default) checked for validity on entry to the relevant functions. Values other than those in the surrogate range U+D800 to U+DFFF are independent code points. Values in the surrogate range must be used in pairs in the correct manner.

If an invalid UTF-16 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first data unit of the failing character. The run-time functions pcre16_exec() and pcre16_dfa_exec() also pass back this information, as well as a more detailed reason code if the caller has provided memory in which to do this.

In some situations, you may already know that your strings are valid, and therefore want to skip these checks in order to improve performance. If you set the PCRE_NO_UTF16_CHECK flag at compile time or at run time, PCRE assumes that the pattern or subject it is given (respectively) contains only valid UTF-16 sequences. In this case, it does not diagnose an invalid UTF-16 string.


General comments about UTF modes

1. Codepoints less than 256 can be specified by either braced or unbraced hexadecimal escape sequences (for example, \x{b3} or \xb3). Larger values have to use braced sequences.

2. Octal numbers up to \777 are recognized, and in UTF-8 mode, they match two-byte characters for values greater than \177.

3. Repeat quantifiers apply to complete UTF characters, not to individual data units, for example: \x{100}{3}.

4. The dot metacharacter matches one UTF character instead of a single data unit.

5. The escape sequence \C can be used to match a single byte in UTF-8 mode, or a single 16-bit data unit in UTF-16 mode, but its use can lead to some strange effects because it breaks up multi-unit characters (see the description of \C in the pcrepattern documentation). The use of \C is not supported in the alternative matching function pcre[16]_dfa_exec(), nor is it supported in UTF mode by the JIT optimization of pcre[16]_exec(). If JIT optimization is requested for a UTF pattern that contains \C, it will not succeed, and so the matching will be carried out by the normal interpretive function.

6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly test characters of any code value, but, by default, the characters that PCRE recognizes as digits, spaces, or word characters remain the same set as in non-UTF mode, all with values less than 256. This remains true even when PCRE is built to include Unicode property support, because to do otherwise would slow down PCRE in many common cases. Note in particular that this applies to \b and \B, because they are defined in terms of \w and \W. If you really want to test for a wider sense of, say, "digit", you can use explicit Unicode property tests such as \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that the character escapes work is changed so that Unicode properties are used to determine which characters match. There are more details in the section on generic character types in the pcrepattern documentation.

7. Similarly, characters that match the POSIX named character classes are all low-valued characters, unless the PCRE_UCP option is set.

8. However, the horizontal and vertical white space matching escapes (\h, \H, \v, and \V) do match all the appropriate Unicode characters, whether or not PCRE_UCP is set.

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. Furthermore, 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 supported by PCRE.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 14 April 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_study.html0000644000222100022210000000371211775533017014077 00000000000000 pcre_study specification

pcre_study man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

pcre_extra *pcre_study(const pcre *code, int options, const char **errptr);

pcre16_extra *pcre16_study(const pcre16 *code, int options, const char **errptr);


DESCRIPTION

This function studies a compiled pattern, to see if additional information can be extracted that might speed up matching. Its arguments are:

  code       A compiled regular expression
  options    Options for pcre[16]_study()
  errptr     Where to put an error message
If the function succeeds, it returns a value that can be passed to pcre[16]_exec() or pcre[16]_dfa_exec() via their extra arguments.

If the function returns NULL, either it could not find any additional information, or there was an error. You can tell the difference by looking at the error value. It is NULL in first case.

The only option is PCRE_STUDY_JIT_COMPILE. It requests just-in-time compilation if possible. If PCRE has been compiled without JIT support, this option is ignored. See the pcrejit page for further details.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_free_study.html0000644000222100022210000000221011775533017015070 00000000000000 pcre_free_study specification

pcre_free_study man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

void pcre_free_study(pcre_extra *extra);

void pcre16_free_study(pcre16_extra *extra);


DESCRIPTION

This function is used to free the memory used for the data generated by a call to pcre[16]_study() when it is no longer needed. The argument must be the result of such a call.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_get_named_substring.html0000644000222100022210000000417211775533017016753 00000000000000 pcre_get_named_substring specification

pcre_get_named_substring man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr);

int pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_SPTR16 *stringptr);


DESCRIPTION

This is a convenience function for extracting a captured substring by name. The arguments are:

  code          Compiled pattern
  subject       Subject that has been successfully matched
  ovector       Offset vector that pcre[16]_exec() used
  stringcount   Value returned by pcre[16]_exec()
  stringname    Name of the required substring
  stringptr     Where to put the string pointer
The memory in which the substring is placed is obtained by calling pcre[16]_malloc(). The convenience function pcre[16]_free_substring() can be used to free it when it is no longer needed. The yield of the function is the length of the extracted substring, PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string name is invalid.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcreapi.html0000644000222100022210000035526011775533017013351 00000000000000 pcreapi specification

pcreapi man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

#include <pcre.h>


PCRE NATIVE API BASIC FUNCTIONS

pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr);

pcre *pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr);

pcre_extra *pcre_study(const pcre *code, int options, const char **errptr);

void pcre_free_study(pcre_extra *extra);

int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize);

int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize, int *workspace, int wscount);


PCRE NATIVE API STRING EXTRACTION FUNCTIONS

int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int buffersize);

int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int buffersize);

int pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr);

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);

int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr);

void pcre_free_substring(const char *stringptr);

void pcre_free_substring_list(const char **stringptr);


PCRE NATIVE API AUXILIARY FUNCTIONS

pcre_jit_stack *pcre_jit_stack_alloc(int startsize, int maxsize);

void pcre_jit_stack_free(pcre_jit_stack *stack);

void pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *data);

const unsigned char *pcre_maketables(void);

int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where);

int pcre_refcount(pcre *code, int adjust);

int pcre_config(int what, void *where);

const char *pcre_version(void);

int pcre_pattern_to_host_byte_order(pcre *code, pcre_extra *extra, const unsigned char *tables);


PCRE NATIVE API INDIRECTED FUNCTIONS

void *(*pcre_malloc)(size_t);

void (*pcre_free)(void *);

void *(*pcre_stack_malloc)(size_t);

void (*pcre_stack_free)(void *);

int (*pcre_callout)(pcre_callout_block *);


PCRE 8-BIT AND 16-BIT LIBRARIES

From release 8.30, PCRE can be compiled as a library for handling 16-bit character strings as well as, or instead of, the original library that handles 8-bit character strings. To avoid too much complication, this document describes the 8-bit versions of the functions, with only occasional references to the 16-bit library.

The 16-bit functions operate in the same way as their 8-bit counterparts; they just use different data types for their arguments and results, and their names start with pcre16_ instead of pcre_. For every option that has UTF8 in its name (for example, PCRE_UTF8), there is a corresponding 16-bit name with UTF8 replaced by UTF16. This facility is in fact just cosmetic; the 16-bit option names define the same bit values.

References to bytes and UTF-8 in this document should be read as references to 16-bit data quantities and UTF-16 when using the 16-bit library, unless specified otherwise. More details of the specific differences for the 16-bit library are given in the pcre16 page.


PCRE API OVERVIEW

PCRE has its own native API, which is described in this document. There are also some wrapper functions (for the 8-bit library only) that correspond to the POSIX regular expression API, but they do not give access to all the functionality. They are described in the pcreposix documentation. Both of these APIs define a set of C function calls. A C++ wrapper (again for the 8-bit library only) is also distributed with PCRE. It is documented in the pcrecpp page.

The native API C function prototypes are defined in the header file pcre.h, and on Unix-like systems the (8-bit) library itself is called libpcre. It can normally be accessed by adding -lpcre to the command for linking an application that uses PCRE. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release numbers for the library. Applications can use these to include support for different releases of PCRE.

In a Windows environment, if you want to statically link an application program against a non-dll pcre.a file, you must define PCRE_STATIC before including pcre.h or pcrecpp.h, because otherwise the pcre_malloc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results.

The functions pcre_compile(), pcre_compile2(), pcre_study(), and pcre_exec() are used for compiling and matching regular expressions in a Perl-compatible manner. A sample program that demonstrates the simplest way of using them is provided in the file called pcredemo.c in the PCRE source distribution. A listing of this program is given in the pcredemo documentation, and the pcresample documentation describes how to compile and run it.

Just-in-time compiler support is an optional feature of PCRE that can be built in appropriate hardware environments. It greatly speeds up the matching performance of many patterns. Simple programs can easily request that it be used if available, by setting an option that is ignored when it is not relevant. More complicated programs might need to make use of the functions pcre_jit_stack_alloc(), pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control the JIT code's memory usage. These functions are discussed in the pcrejit documentation.

A second matching function, pcre_dfa_exec(), which is not Perl-compatible, is also provided. This uses a different algorithm for the matching. The alternative algorithm finds all possible matches (at a given point in the subject), and scans the subject just once (unless there are lookbehind assertions). 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 documentation.

In addition to the main compiling and matching functions, there are convenience functions for extracting captured substrings from a subject string that is matched by pcre_exec(). They are:

  pcre_copy_substring()
  pcre_copy_named_substring()
  pcre_get_substring()
  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.

The function pcre_maketables() is used to build a set of character tables in the current locale for passing to pcre_compile(), pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is provided for specialist use. Most commonly, no special tables are passed, in which case internal tables that are generated when PCRE is built are used.

The function pcre_fullinfo() is used to find out information about a compiled pattern. The function pcre_version() returns a pointer to a string containing the version of PCRE and its date of release.

The function pcre_refcount() maintains a reference count in a data block containing a compiled pattern. This is provided for the benefit of object-oriented applications.

The global variables pcre_malloc and pcre_free initially contain the entry points of the standard malloc() and free() functions, respectively. PCRE calls the memory management functions via these variables, so a calling program can replace them if it wishes to intercept the calls. This should be done before calling any PCRE functions.

The global variables pcre_stack_malloc and pcre_stack_free are also 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. See the pcrebuild documentation for details of how to do this. It is a non-standard way of building PCRE, for use in environments 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 documentation.

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 specified points during a matching operation. Details are given in the pcrecallout documentation.


NEWLINES

PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (linefeed) character, the two-character sequence CRLF, any of the three preceding, or any Unicode newline sequence. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029).

Each of the first three conventions is used by at least one operating system as its standard newline sequence. 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.

At compile time, the newline convention can be specified by the options argument of pcre_compile(), or it can be specified by special text at the start of the pattern itself; this overrides any other settings. See the pcrepattern page for details of the special character sequences.

In the PCRE documentation the word "newline" is used to mean "the character or pair of characters that indicate a line break". The choice of newline convention affects the handling of the dot, circumflex, and dollar metacharacters, the handling of #-comments in /x mode, and, when CRLF is a recognized line ending sequence, the match position advancement for a non-anchored pattern. There is more detail about this in the section on pcre_exec() options below.

The choice of newline convention does not affect the interpretation of the \n or \r escape sequences, nor does it affect what \R matches, which is controlled in a similar way, but by separate options.


MULTITHREADING

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 matching, so the same compiled pattern can safely be used by several threads at once.

If the just-in-time optimization feature is being used, it needs separate memory stack areas for each thread. See the pcrejit documentation for more details.


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 pcreprecompile documentation, which includes a description of the pcre_pattern_to_host_byte_order() function. However, compiling a regular expression with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes.


CHECKING BUILD-TIME OPTIONS

int pcre_config(int what, void *where);

The function pcre_config() makes it possible for a PCRE client to discover which optional features have been compiled into the PCRE library. The pcrebuild documentation has more details about these optional features.

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 returned value is zero on success, or the negative error code PCRE_ERROR_BADOPTION if the value in the first argument is not recognized. The following information is available:

  PCRE_CONFIG_UTF8
The output is an integer that is set to one if UTF-8 support is available; otherwise it is set to zero. If this option is given to the 16-bit version of this function, pcre16_config(), the result is PCRE_ERROR_BADOPTION.
  PCRE_CONFIG_UTF16
The output is an integer that is set to one if UTF-16 support is available; otherwise it is set to zero. This value should normally be given to the 16-bit version of this function, pcre16_config(). If it is given to the 8-bit version of this function, the result is PCRE_ERROR_BADOPTION.
  PCRE_CONFIG_UNICODE_PROPERTIES
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_JIT
The output is an integer that is set to one if support for just-in-time compiling is available; otherwise it is set to zero.
  PCRE_CONFIG_JITTARGET
The output is a pointer to a zero-terminated "const char *" string. If JIT support is available, the string contains the name of the architecture for which the JIT compiler is configured, for example "x86 32bit (little endian + unaligned)". If JIT support is not available, the result is NULL.
  PCRE_CONFIG_NEWLINE
The output is an integer whose value specifies the default character sequence that is recognized as meaning "newline". The four values that are supported are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for ANYCRLF, and -1 for ANY. Though they are derived from ASCII, the same values are returned in EBCDIC environments. The default should normally correspond to the standard sequence for your operating system.
  PCRE_CONFIG_BSR
The output is an integer whose value indicates what character sequences the \R escape sequence matches by default. A value of 0 means that \R matches any Unicode line ending sequence; a value of 1 means that \R matches only CR, LF, or CRLF. The default can be overridden when a pattern is compiled or matched.
  PCRE_CONFIG_LINK_SIZE
The output is an integer that contains the number of bytes used for internal linkage in compiled regular expressions. For the 8-bit library, the value can be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still a number of bytes. 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. Larger values allow larger regular expressions to be compiled, at the expense of slower matching.
  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 given in the pcreposix documentation.
  PCRE_CONFIG_MATCH_LIMIT
The output is a long integer that gives the default limit for the number of 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 a long 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 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 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 blocks on the heap, thus avoiding the use of the stack.


COMPILING A PATTERN

pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); pcre *pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr);

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, errorcodeptr, via which a numerical error code can be returned. To avoid too much repetition, we refer just to pcre_compile() below, but the information applies equally to pcre_compile2().

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 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 (via pcre_free) when it is no longer required.

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 argument, which is an address (see below).

The options argument contains various bit settings that affect the compilation. 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, but some others as well) can also be set and unset from within the pattern (see the detailed description in the pcrepattern documentation). For those options that can be different in different parts of the pattern, the contents of the options argument specifies their settings at the start of compilation and execution. The PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and PCRE_NO_START_OPTIMIZE 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 sets the variable pointed to by errptr 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. Normally, the offset from the start of the pattern to the byte that was being processed when 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 given). However, for an invalid UTF-8 string, the offset is that of the first byte of the failing character.

Some errors are not detected until the whole pattern has been scanned; in these cases, the offset passed back is the length of the pattern. Note that the offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point into the middle of a UTF-8 character.

If pcre_compile2() is used instead of pcre_compile(), and the errorcodeptr 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 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_compile():

  pcre *re;
  const char *error;
  int erroffset;
  re = pcre_compile(
    "^A.*Z",          /* the pattern */
    0,                /* default options */
    &error,           /* for error message */
    &erroffset,       /* for error offset */
    NULL);            /* use default character tables */
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 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 callout facility, see the pcrecallout documentation.
  PCRE_BSR_ANYCRLF
  PCRE_BSR_UNICODE
These options (which are mutually exclusive) control what the \R escape sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. The default is specified when PCRE is built. It can be overridden from within the pattern, or by setting an option when a compiled pattern is matched.
  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 compiled 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 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 metacharacter in the pattern matches a character of any value, including one that indicates a newline. However, it only ever matches one character, even if newlines are coded as CRLF. Without this option, 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 newline characters, 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, white space 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, characters between an unescaped # outside a character class and the next newline, 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.

Which characters are interpreted as newlines is controlled by the options passed to pcre_compile() or by a special sequence at the start of the pattern, as described in the section entitled "Newline conventions" in the pcrepattern documentation. Note that the end of this type of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count.

This option makes it possible to include comments inside complicated patterns. Note, however, that this applies only to data characters. White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that 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. (Perl can, however, be persuaded to give an error for this, by running it with the -w option.) 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 in the subject string, though the matched text may continue over the newline.
  PCRE_JAVASCRIPT_COMPAT
If this option is set, PCRE's behaviour is changed in some ways so that it is compatible with JavaScript rather than Perl. The changes are as follows:

(1) A lone closing square bracket in a pattern causes a compile-time error, because this is illegal in JavaScript (by default it is treated as a data character). Thus, the pattern AB]CD becomes illegal when this option is set.

(2) At run time, a back reference to an unset subpattern group matches an empty string (by default this causes the current matching alternative to fail). A pattern such as (\1)(a) succeeds when this option is set (assuming it can find an "a" in the subject), whereas it fails by default, for Perl compatibility.

(3) \U matches an upper case "U" character; by default \U causes a compile time error (Perl uses \U to upper case subsequent characters).

(4) \u matches a lower case "u" character unless it is followed by four hexadecimal digits, in which case the hexadecimal number defines the code point to match. By default, \u causes a compile time error (Perl uses it to upper case the following character).

(5) \x matches a lower case "x" character unless it is followed by two hexadecimal digits, in which case the hexadecimal number defines the code point to match. By default, as in Perl, a hexadecimal number is always expected after \x, but it may have zero, one, or two digits (so, for example, \xz matches a binary zero character followed by z).

  PCRE_MULTILINE
By default, PCRE treats the subject string as consisting of a single line of characters (even if it actually contains newlines). The "start of line" metacharacter (^) matches only at the start of the string, while the "end of line" metacharacter ($) matches only at the end of the string, or before a terminating newline (unless PCRE_DOLLAR_ENDONLY 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 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 newlines 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
  PCRE_NEWLINE_ANYCRLF
  PCRE_NEWLINE_ANY
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 PCRE_NEWLINE_CRLF specifies that a newline is indicated by the two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies that any of the three preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit library, the last two are recognized only in UTF-8 mode.

The newline setting in the options word uses three bits that are treated as a number, giving eight possibilities. Currently only six are used (default plus the five values above). This means that if you set more than one newline option, the combination may or may not be sensible. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and cause an error.

The only time that a line break in a pattern is specially recognized when compiling is when PCRE_EXTENDED is set. CR and LF are white space characters, and so are ignored in this mode. Also, an unescaped # outside a character class indicates a comment that lasts until after the next line break sequence. In other circumstances, line break sequences in patterns are treated as literal data.

The newline option that is 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 parentheses 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.
  NO_START_OPTIMIZE
This is an option that acts at matching time; that is, it is really an option for pcre_exec() or pcre_dfa_exec(). If it is set at compile time, it is remembered with the compiled pattern and assumed at matching time. For details see the discussion of PCRE_NO_START_OPTIMIZE below.
  PCRE_UCP
This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, \w, and some of the POSIX character classes. By default, only ASCII characters are recognized, but if PCRE_UCP is set, Unicode properties are used instead to classify characters. More details are given in the section on generic character types in the pcrepattern page. If you set PCRE_UCP, matching one of the items it affects takes much longer. The option is available only if PCRE has been compiled with Unicode property support.
  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 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 strings. However, it is available only when PCRE is built to include UTF support. If not, the use of this option provokes an error. Details of how this option changes the behaviour of PCRE are given in the pcreunicode page.
  PCRE_NO_UTF8_CHECK
When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is automatically checked. There is a discussion about the validity of UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence 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 validity checking 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 both compiling functions. Note that error messages are always 8-bit ASCII strings, even in 16-bit mode. As PCRE has developed, some error codes have fallen out of use. To avoid confusion, they have not been re-used.

   0  no error
   1  \ at end of pattern
   2  \c at end of pattern
   3  unrecognized character follows \
   4  numbers out of order in {} quantifier
   5  number too big in {} quantifier
   6  missing terminating ] for character class
   7  invalid escape sequence in character class
   8  range out of order in character class
   9  nothing to repeat
  10  [this code is not in use]
  11  internal error: unexpected repeat
  12  unrecognized character after (? or (?-
  13  POSIX named classes are supported only within a class
  14  missing )
  15  reference to non-existent subpattern
  16  erroffset passed as NULL
  17  unknown option bit(s) set
  18  missing ) after comment
  19  [this code is not in use]
  20  regular expression is too large
  21  failed to get memory
  22  unmatched parentheses
  23  internal error: code overflow
  24  unrecognized character after (?<
  25  lookbehind assertion is not fixed length
  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 )
  30  unknown POSIX class name
  31  POSIX collating elements are not supported
  32  this version of PCRE is compiled without UTF support
  33  [this code is not in use]
  34  character value in \x{...} sequence is too large
  35  invalid condition (?(0)
  36  \C not allowed in lookbehind assertion
  37  PCRE does not support \L, \l, \N{name}, \U, or \u
  38  number after (?C is > 255
  39  closing ) for (?C expected
  40  recursive call could loop indefinitely
  41  unrecognized character after (?P
  42  syntax error in subpattern name (missing terminator)
  43  two named subpatterns have the same name
  44  invalid UTF-8 string (specifically UTF-8)
  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 10000)
  50  [this code is not in use]
  51  octal value is greater than \377 in 8-bit non-UTF-8 mode
  52  internal error: overran compiling workspace
  53  internal error: previously-checked referenced subpattern
        not found
  54  DEFINE group contains more than one branch
  55  repeating a DEFINE group is not allowed
  56  inconsistent NEWLINE options
  57  \g is not followed by a braced, angle-bracketed, or quoted
        name/number or by a plain number
  58  a numbered reference must not be zero
  59  an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)
  60  (*VERB) not recognized
  61  number is too big
  62  subpattern name expected
  63  digit expected after (?+
  64  ] is an invalid data character in JavaScript compatibility mode
  65  different names for subpatterns of the same number are
        not allowed
  66  (*MARK) must have an argument
  67  this version of PCRE is not compiled with Unicode property
        support
  68  \c must be followed by an ASCII character
  69  \k is not followed by a braced, angle-bracketed, or quoted name
  70  internal error: unknown opcode in find_fixedlength()
  71  \N is not supported in a class
  72  too many forward references
  73  disallowed Unicode code point (>= 0xd800 && <= 0xdfff)
  74  invalid UTF-16 string (specifically UTF-16)
  75  name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
  76  character value in \u.... sequence is too large
The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built.


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 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 pattern 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 the results of the study.

The returned value from pcre_study() can be passed directly to pcre_exec() or pcre_dfa_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 useful information, pcre_study() returns NULL. In that circumstance, if the calling program wants to pass any of the other fields to pcre_exec() or pcre_dfa_exec(), it must set up its own pcre_extra block.

The second argument of pcre_study() contains option bits. There are three options:

  PCRE_STUDY_JIT_COMPILE
  PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
  PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
If any of these are set, and the just-in-time compiler is available, the pattern is further compiled into machine code that executes much faster than the pcre_exec() interpretive matching function. If the just-in-time compiler is not available, these options are ignored. All other bits in the options argument must be zero.

JIT compilation is a heavyweight optimization. It can take some time for patterns to be analyzed, and for one-off matches and simple patterns the benefit of faster execution might be offset by a much slower study time. Not all patterns can be optimized by the JIT compiler. For those that cannot be handled, matching automatically falls back to the pcre_exec() interpreter. For more details, see the pcrejit documentation.

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 after calling pcre_study(), to be sure that it has run successfully.

When you are finished with a pattern, you can free the memory used for the study data by calling pcre_free_study(). This function was added to the API for release 8.20. For earlier versions, the memory could be freed with pcre_free(), just like the pattern itself. This will still work in cases where JIT optimization is not used, but it is advisable to change to the new function when convenient.

This is a typical way in which pcre_study() is used (except that in a real application there should be tests for errors):

  int rc;
  pcre *re;
  pcre_extra *sd;
  re = pcre_compile("pattern", 0, &error, &erroroffset, NULL);
  sd = pcre_study(
    re,             /* result of pcre_compile() */
    0,              /* no options */
    &error);        /* set to NULL or points to a message */
  rc = pcre_exec(   /* see below for details of pcre_exec() options */
    re, sd, "subject", 7, 0, 0, ovector, 30);
  ...
  pcre_free_study(sd);
  pcre_free(re);
Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not mean that there are any strings of that length that match, but it does guarantee that no shorter strings match. The value is used by pcre_exec() and pcre_dfa_exec() to avoid wasting time by trying to match strings that are shorter than the lower bound. You can find out the value in a calling program via the pcre_fullinfo() function.

Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at which to start matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256.)

These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), and the information is also used by the JIT compiler. The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_exec() or pcre_dfa_exec(), but if this is done, JIT execution is also disabled. You might want to do this if your pattern contains callouts or (*MARK) and you want to make use of these facilities in cases where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE below.


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. By default, higher-valued codes never match escapes such as \w or \d, but they can be tested with \p if PCRE is built with Unicode character property support. Alternatively, the PCRE_UCP option can be set at compile time; this causes \w and friends to use Unicode property support instead of built-in tables. The use of locales with Unicode is discouraged. If you are handling characters with codes greater than 128, you should either use UTF-8 and Unicode, or use locales, but not try to mix the two.

PCRE contains an internal set of tables that are used when the final argument of pcre_compile() is NULL. These are sufficient for many applications. Normally, the internal tables recognize only ASCII characters. However, when PCRE is built, it is possible to cause the internal tables to be rebuilt in the default "C" locale of the local system, which may cause them to be different.

The internal tables can always be overridden by tables supplied by the application that calls PCRE. 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 treated as letters), the following code could be used:

  setlocale(LC_CTYPE, "fr_FR");
  tables = pcre_maketables();
  re = pcre_compile(..., tables);
The locale name "fr_FR" is used on Linux and other Unix-like systems; if you are using Windows, the name for the French locale is "french".

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() and normally also by pcre_exec(). Thus, by default, for any single pattern, 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 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.


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 pattern. It replaces the pcre_info() function, which was removed from the library at version 8.30, after more than 10 years of obsolescence.

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
                            the argument where was NULL
  PCRE_ERROR_BADMAGIC       the "magic number" was not found
  PCRE_ERROR_BADENDIANNESS  the pattern was compiled with different
                            endianness
  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. The endianness error can occur if a compiled pattern is saved and reloaded on a different host. Here is a typical call of pcre_fullinfo(), to obtain the length of the compiled pattern:
  int rc;
  size_t length;
  rc = pcre_fullinfo(
    re,               /* result of pcre_compile() */
    sd,               /* 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 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 there are no back references.
  PCRE_INFO_CAPTURECOUNT
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 information call is provided for internal use by the pcre_study() function. External callers can cause PCRE to use its internal tables by passing a NULL table pointer.
  PCRE_INFO_FIRSTBYTE
Return information about the first data unit of any matched string, for a non-anchored pattern. (The name of this option refers to the 8-bit library, where data units are bytes.) The fourth argument should point to an int variable.

If there is a fixed first value, for example, the letter "c" from a pattern such as (cat|cow|coyote), its value is returned. In the 8-bit library, the value is always less than 256; in the 16-bit library the value can be up to 0xffff.

If there is no fixed first value, and if either

(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or

(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set (if it were set, the pattern would be anchored),

-1 is returned, indicating that the pattern matches only at the start of a subject string or after any newline within the string. Otherwise -2 is returned. For anchored patterns, -2 is returned.

  PCRE_INFO_FIRSTTABLE
If the pattern was studied, and this resulted in the construction of a 256-bit table indicating a fixed set of values for the first data unit in any matching string, a pointer to the table is returned. Otherwise NULL is returned. The fourth argument should point to an unsigned char * variable.
  PCRE_INFO_HASCRORLF
Return 1 if the pattern contains any explicit matches for CR or LF characters, otherwise 0. The fourth argument should point to an int variable. An explicit match is either a literal CR or LF character, or \r or \n.
  PCRE_INFO_JCHANGED
Return 1 if the (?J) or (?-J) option setting is used in the pattern, otherwise 0. The fourth argument should point to an int variable. (?J) and (?-J) set and unset the local PCRE_DUPNAMES option, respectively.
  PCRE_INFO_JIT
Return 1 if the pattern was studied with one of the JIT options, and just-in-time compiling was successful. The fourth argument should point to an int variable. A return value of 0 means that JIT support is not available in this version of PCRE, or that the pattern was not studied with a JIT option, or that the JIT compiler could not handle this particular pattern. See the pcrejit documentation for details of what can and cannot be handled.
  PCRE_INFO_JITSIZE
If the pattern was successfully studied with a JIT option, return the size of the JIT compiled code, otherwise return zero. The fourth argument should point to a size_t variable.
  PCRE_INFO_LASTLITERAL
Return the value of the rightmost literal data unit that must exist in any matched string, other than at its start, if such a value has been recorded. The fourth argument should point to an int variable. If there is no such value, -1 is returned. For anchored patterns, a last literal value is recorded only if it follows something of variable length. For example, for the pattern /^a\d+z\d+/ the returned value is "z", but for /^a\dz\d/ the returned value is -1.
  PCRE_INFO_MAXLOOKBEHIND
Return the number of characters (NB not bytes) in the longest lookbehind assertion in the pattern. Note that the simple assertions \b and \B require a one-character lookbehind. This information is useful when doing multi-segment matching using the partial matching facilities.
  PCRE_INFO_MINLENGTH
If the pattern was studied and a minimum length for matching subject strings was computed, its value is returned. Otherwise the returned value is -1. The value is a number of characters, which in UTF-8 mode may be different from the number of bytes. The fourth argument should point to an int variable. A non-negative value is a lower bound to the length of any matching string. There may not be any strings of that length that do actually match, but every string that does match is at least that long.
  PCRE_INFO_NAMECOUNT
  PCRE_INFO_NAMEENTRYSIZE
  PCRE_INFO_NAMETABLE
PCRE supports the use of named as well as numbered capturing parentheses. The names are just an additional way of identifying the parentheses, which still acquire numbers. Several convenience functions such as pcre_get_named_substring() are provided for extracting captured substrings 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 of each entry; both of these return an int value. The entry size depends on the length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first entry of the table. This is a pointer to char in the 8-bit library, where the first two bytes of each entry are the number of the capturing parenthesis, most significant byte first. In the 16-bit library, the pointer points to 16-bit data units, the first of which contains the parenthesis number. The rest of the entry is the corresponding name, zero terminated.

The names are in alphabetical order. Duplicate names may appear if (?| is used to create multiple groups with the same number, as described in the section on duplicate subpattern numbers in the pcrepattern page. Duplicate names for subpatterns with different numbers are permitted only if PCRE_DUPNAMES is set. In all cases of duplicate names, they appear in the table in the order in which they were found in the pattern. In the absence of (?| this is the order of increasing number; when (?| is used this is not necessarily the case because later subpatterns may have lower numbers.

As a simple example of the name/number table, consider the following pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white space - including newlines - is ignored):

  (?<date> (?<year>(\d\d)?\d\d) - (?<month>\d\d) - (?<day>\d\d) )
There are four named subpatterns, so the table has four entries, and each entry in the table is eight bytes long. The table is as follows, with non-printing bytes shows in hexadecimal, and undefined bytes shown as ??:
  00 01 d  a  t  e  00 ??
  00 05 d  a  y  00 ?? ??
  00 04 m  o  n  t  h  00
  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 the entries is likely to be different for each compiled pattern.
  PCRE_INFO_OKPARTIAL
Return 1 if the pattern can be used for partial matching with pcre_exec(), otherwise 0. The fourth argument should point to an int variable. From release 8.00, this always returns 1, because the restrictions that previously applied to partial matching have been lifted. The pcrepartial documentation gives details of partial matching.
  PCRE_INFO_OPTIONS
Return a copy of the options with which the pattern was compiled. The fourth argument should point to an unsigned long int variable. These option bits are those specified in the call to pcre_compile(), modified by any top-level option settings at the start of the pattern itself. In other words, they are the options that will be in force when matching starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, and PCRE_EXTENDED.

A pattern is automatically anchored by PCRE if all of its top-level alternatives begin with one of the following:

  ^     unless PCRE_MULTILINE is set
  \A    always
  \G    always
  .*    if PCRE_DOTALL is set and there are no back references to the subpattern in which .* appears
For such patterns, the PCRE_ANCHORED bit is set in the options returned by pcre_fullinfo().
  PCRE_INFO_SIZE
Return the size of the compiled pattern in bytes (for both libraries). The fourth argument should point to a size_t variable. This value does not include the size of the pcre structure that is returned by pcre_compile(). The value that is passed as the argument to pcre_malloc() when pcre_compile() is getting memory in which to place the compiled data is the value returned by this option plus the size of the pcre structure. Studying a compiled pattern, with or without JIT, does not alter the value returned by this option.
  PCRE_INFO_STUDYSIZE
Return the size in bytes of the data block pointed to by the study_data field in a pcre_extra block. If pcre_extra is NULL, or there is no study data, zero is returned. The fourth argument should point to a size_t variable. The study_data field is set by pcre_study() to record information that will speed up matching (see the section entitled "Studying a pattern" above). The format of the study_data block is private, but its length is made available via this option so that it can be saved and restored (see the pcreprecompile documentation for details).


REFERENCE COUNTS

int pcre_refcount(pcre *code, int adjust);

The pcre_refcount() function is used to maintain a reference count in the data block that contains a compiled pattern. It is provided for the benefit of applications that operate in an object-oriented manner, where different parts of the application may be using the same compiled pattern, but you want to free the block when they are all done.

When a pattern is compiled, the reference count field is initialized to zero. It is changed only by calling this function, whose action is to add the adjust value (which may be positive or negative) to it. The yield of the function is the new value. However, the value of the count is constrained to lie between 0 and 65535, inclusive. If the new value is outside these limits, it is forced to the appropriate limit value.

Except when it is zero, the reference count is not correctly preserved if a pattern is compiled on one host and then transferred to a host whose byte-order is different. (This seems a highly unlikely scenario.)


MATCHING A PATTERN: THE TRADITIONAL FUNCTION

int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize);

The function pcre_exec() is called to match a subject string against a compiled pattern, which is passed in the code argument. If the pattern was studied, the result of the study should be passed in the extra argument. You can call pcre_exec() with the same code and extra arguments as many times as you like, in order to match different subject strings with the same pattern.

This function is the main matching facility of the library, and it operates in a Perl-like manner. For specialist use there is also an alternative matching function, which is described below in the section about the pcre_dfa_exec() function.

In most applications, the pattern will have been compiled (and optionally studied) in the same process that calls pcre_exec(). However, it is possible to save compiled patterns and study data, and then use them later in different processes, possibly even on different hosts. For a discussion about this, see the pcreprecompile documentation.

Here is an example of a simple call to pcre_exec():

  int rc;
  int ovector[30];
  rc = pcre_exec(
    re,             /* result of pcre_compile() */
    NULL,           /* we didn't study the pattern */
    "some string",  /* the subject string */
    11,             /* the length of the subject string */
    0,              /* start at offset 0 in the subject */
    0,              /* default options */
    ovector,        /* vector of integers for substring information */
    30);            /* number of elements (NOT size in bytes) */


Extra data for pcre_exec()

If the extra argument is not NULL, it must point to a pcre_extra data block. The pcre_study() function returns such a block (when it doesn't return NULL), but you can also create one for yourself, and pass additional information in it. The pcre_extra block contains the following fields (not necessarily in this order):

  unsigned long int flags;
  void *study_data;
  void *executable_jit;
  unsigned long int match_limit;
  unsigned long int match_limit_recursion;
  void *callout_data;
  const unsigned char *tables;
  unsigned char **mark;
In the 16-bit version of this structure, the mark field has type "PCRE_UCHAR16 **".

The flags field is used to specify which of the other fields are set. The flag bits are:

  PCRE_EXTRA_CALLOUT_DATA
  PCRE_EXTRA_EXECUTABLE_JIT
  PCRE_EXTRA_MARK
  PCRE_EXTRA_MATCH_LIMIT
  PCRE_EXTRA_MATCH_LIMIT_RECURSION
  PCRE_EXTRA_STUDY_DATA
  PCRE_EXTRA_TABLES
Other flag bits should be set to zero. The study_data field and sometimes the executable_jit field are set in the pcre_extra block that is returned by pcre_study(), together with the appropriate flag bits. You should not set these yourself, but you may add to the block by setting other fields and their corresponding flag bits.

The match_limit field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats.

Internally, pcre_exec() uses a function called match(), which it calls repeatedly (sometimes recursively). The limit set by match_limit is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. For patterns that are not anchored, the count restarts from zero for each position in the subject string.

When pcre_exec() is called with a pattern that was successfully studied with a JIT option, the way that the matching is executed is entirely different. However, there is still the possibility of runaway matching that goes on for a very long time, and so the match_limit value is also used in this case (but in a different way) to limit how long the matching can continue.

The default value for the limit can be set when PCRE is built; the default default is 10 million, which handles all but the most extreme cases. You can override the default by suppling pcre_exec() with a pcre_extra block in which match_limit is set, and PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT.

The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursion. The recursion depth is a smaller number than the total number of calls, because not all calls to match() are recursive. This limit is of use only if it is set smaller than match_limit.

Limiting the recursion depth limits the amount of machine stack that can be used, or, when PCRE has been compiled to use memory on the heap instead of the stack, the amount of heap memory that can be used. This limit is not relevant, and is ignored, when matching is done using JIT compiled code.

The default value for match_limit_recursion can be set when PCRE is built; the default default is the same value as the default for match_limit. You can override the default by suppling pcre_exec() with a pcre_extra block in which match_limit_recursion is set, and PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT.

The callout_data field is used in conjunction with the "callout" feature, and is described in the pcrecallout documentation.

The tables field is used to pass a character tables pointer to pcre_exec(); this overrides the value that is stored with the compiled pattern. A non-NULL value is stored with the compiled pattern only if custom tables were supplied to pcre_compile() via its tableptr argument. If NULL is passed to pcre_exec() using this mechanism, it forces PCRE's internal tables to be used. This facility is helpful when re-using patterns that have been saved after compiling with an external set of tables, because the external tables might be at a different address when pcre_exec() is called. See the pcreprecompile documentation for a discussion of saving compiled patterns for later use.

If PCRE_EXTRA_MARK is set in the flags field, the mark field must be set to point to a suitable variable. If the pattern contains any backtracking control verbs such as (*MARK:NAME), and the execution ends up with a name to pass back, a pointer to the name string (zero terminated) is placed in the variable pointed to by the mark field. The names are within the compiled pattern; if you wish to retain such a name you must copy it before freeing the memory of a compiled pattern. If there is no name to pass back, the variable pointed to by the mark field is set to NULL. For details of the backtracking control verbs, see the section entitled "Backtracking control" in the pcrepattern documentation.


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_NEWLINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT.

If the pattern was successfully studied with one of the just-in-time (JIT) compile options, the only supported options for JIT execution are PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an unsupported option is used, JIT execution is disabled and the normal interpretive code in pcre_exec() is run.

  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 unachored at matching time.
  PCRE_BSR_ANYCRLF
  PCRE_BSR_UNICODE
These options (which are mutually exclusive) control what the \R escape sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. These options override the choice that was made or defaulted when the pattern was compiled.
  PCRE_NEWLINE_CR
  PCRE_NEWLINE_LF
  PCRE_NEWLINE_CRLF
  PCRE_NEWLINE_ANYCRLF
  PCRE_NEWLINE_ANY
These options override the newline definition that was chosen or defaulted when the pattern was compiled. For details, see the description of pcre_compile() above. During matching, the newline choice affects the behaviour of the dot, circumflex, and dollar metacharacters. It may also alter the way the match position is advanced after a match failure for an unanchored pattern.

When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is set, and a match attempt for an unanchored pattern fails when the current position is at a CRLF sequence, and the pattern contains no explicit matches for CR or LF characters, the match position is advanced by two characters instead of one, in other words, to after the CRLF.

The above rule is a compromise that makes the most common cases work as expected. For example, if the pattern is .+A (and the PCRE_DOTALL option is not set), it does not match the string "\r\nA" because, after failing at the start, it skips both the CR and the LF before retrying. However, the pattern [\r\n]A does match that string, because it contains an explicit CR or LF reference, and so advances only by one character after the first failure.

An explicit match for CR of LF is either a literal appearance of one of those characters, or one of the \r or \n escape sequences. Implicit matches such as [^X] do not count, nor does \s (which includes CR and LF in the characters that it matches).

Notwithstanding the above, anomalous effects may still occur when CRLF is a valid newline sequence and explicit \r or \n escapes appear in the pattern.

  PCRE_NOTBOL
This option specifies that first character of the subject string is not the beginning of a line, so the circumflex metacharacter should not match before it. Setting this without PCRE_MULTILINE (at compile time) causes circumflex never to match. This option affects only the behaviour of the circumflex metacharacter. It does not affect \A.
  PCRE_NOTEOL
This option specifies that the end of the subject string is not the end of a line, so the dollar metacharacter should not match it nor (except in multiline mode) a newline immediately before it. Setting this without PCRE_MULTILINE (at compile time) causes dollar never to match. This option affects only the behaviour of the dollar metacharacter. It does not affect \Z or \z.
  PCRE_NOTEMPTY
An empty string is not considered to be a valid match if this option is set. If there are alternatives in the pattern, they are tried. If all the alternatives match the empty string, the entire match fails. For example, if the pattern
  a?b?
is applied to a string not beginning with "a" or "b", it matches an empty string at the start of the subject. With PCRE_NOTEMPTY set, this match is not valid, so PCRE searches further into the string for occurrences of "a" or "b".
  PCRE_NOTEMPTY_ATSTART
This is like PCRE_NOTEMPTY, except that an empty string match that is not at the start of the subject is permitted. If the pattern is anchored, such a match can occur only if the pattern contains \K.

Perl has no direct equivalent of PCRE_NOTEMPTY or PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern match of the empty string within its split() function, and when using the /g modifier. It is possible to emulate Perl's behaviour after matching a null string by first trying the match again at the same offset with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that fails, by advancing the starting offset (see below) and trying an ordinary match again. There is some code that demonstrates how to do this in the pcredemo sample program. In the most general case, you have to check to see if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one.

  PCRE_NO_START_OPTIMIZE
There are a number of optimizations that pcre_exec() uses at the start of a match, in order to speed up the process. For example, if it is known that an unanchored match must start with a specific character, it searches the subject for that character, and fails immediately if it cannot find it, without actually running the main matching function. This means that a special item such as (*COMMIT) at the start of a pattern is not considered until after a suitable starting point for the match has been found. When callouts or (*MARK) items are in use, these "start-up" optimizations can cause them to be skipped if the pattern is never actually used. The start-up optimizations are in effect a pre-scan of the subject that takes place before the pattern is run.

The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly causing performance to suffer, but ensuring that in cases where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching is always done using interpretively.

Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern

  (*COMMIT)ABC
When this is compiled, PCRE records the fact that a match must start with the character "A". Suppose the subject string is "DEFABC". The start-up optimization scans along the subject, finds "A" and runs the first match attempt from there. The (*COMMIT) item means that the pattern must match the current starting position, which in this case, it does. However, if the same match is run with PCRE_NO_START_OPTIMIZE set, the initial scan along the subject string does not happen. The first match attempt is run starting from "D" and when this fails, (*COMMIT) prevents any further matches being tried, so the overall result is "no match". If the pattern is studied, more start-up optimizations may be used. For example, a minimum length for the subject may be recorded. Consider the pattern
  (*MARK:A)(X|Y)
The minimum length for a match is one character. If the subject is "ABC", there will be attempts to match "ABC", "BC", "C", and then finally an empty string. If the pattern is studied, the final attempt does not take place, because PCRE knows that the subject is too short, and so the (*MARK) is never encountered. In this case, studying the pattern does not affect the overall match result, which is still "no match", but it does affect the auxiliary information that is returned.
  PCRE_NO_UTF8_CHECK
When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8 string is automatically checked when pcre_exec() is subsequently called. The entire string is checked before any other processing takes place. The value of startoffset is also checked to ensure that it points to the start of a UTF-8 character. There is a discussion about the validity of UTF-8 strings in the pcreunicode page. If an invalid sequence of bytes is found, pcre_exec() returns the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In both cases, information about the precise nature of the error may also be returned (see the descriptions of these errors in the section entitled \fIError return values from\fP pcre_exec() below). If startoffset contains a value that does not point to the start of a UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned.

If you already know that your subject is valid, and you want to skip these checks for performance reasons, you can set the PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to do this for the second and subsequent calls to pcre_exec() if you are making repeated calls to find all the matches in a single subject string. However, you should be sure that the value of startoffset points to the start of a character (or the end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a subject or an invalid value of startoffset is undefined. Your program may crash.

  PCRE_PARTIAL_HARD
  PCRE_PARTIAL_SOFT
These options turn on the partial matching feature. For backwards compatibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial match occurs if the end of the subject string is reached successfully, but there are not enough subject characters to complete the match. If this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set, matching continues by testing any remaining alternatives. Only if no complete match can be found is PCRE_ERROR_PARTIAL returned instead of PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the caller is prepared to handle a partial match, but only if no complete match can be found.

If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this case, if a partial match is found, pcre_exec() immediately returns PCRE_ERROR_PARTIAL, without considering any other alternatives. In other words, when PCRE_PARTIAL_HARD is set, a partial match is considered to be more important that an alternative complete match.

In both cases, the portion of the string that was inspected when the partial match was found is set as the first matching string. There is a more detailed discussion of partial and multi-segment matching, with examples, in the pcrepartial documentation.


The string to be matched by pcre_exec()

The subject string is passed to pcre_exec() as a pointer in subject, a length in bytes in length, and a starting byte offset in startoffset. If this is negative or greater than the length of the subject, pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is zero, the search for a match starts at the beginning of the subject, and this is by far the most common case. In UTF-8 mode, the byte offset must point to the start of a UTF-8 character (or the end of the subject). Unlike the pattern string, the subject may contain binary zero bytes.

A non-zero starting offset is useful when searching for another match in the same subject by calling pcre_exec() again after a previous success. Setting startoffset differs from just passing over a shortened string and setting PCRE_NOTBOL in the case of a pattern that begins with any kind of lookbehind. For example, consider the pattern

  \Biss\B
which finds occurrences of "iss" in the middle of words. (\B matches only if the current position in the subject is not a word boundary.) When applied to the string "Mississipi" the first call to pcre_exec() finds the first occurrence. If pcre_exec() is called again with just the remainder of the subject, namely "issipi", it does not match, because \B is always false at the start of the subject, which is deemed to be a word boundary. However, if pcre_exec() is passed the entire string again, but with startoffset set to 4, it finds the second occurrence of "iss" because it is able to look behind the starting point to discover that it is preceded by a letter.

Finding all the matches in a subject is tricky when the pattern can match an empty string. It is possible to emulate Perl's /g behaviour by first trying the match again at the same offset, with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that fails, advancing the starting offset and trying an ordinary match again. There is some code that demonstrates how to do this in the pcredemo sample program. In the most general case, you have to check to see if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one.

If a non-zero starting offset is passed when the pattern is anchored, one attempt to match at the given offset is made. This can only succeed if the pattern does not require the match to be at the start of the subject.


How pcre_exec() returns captured substrings

In general, a pattern matches a certain portion of the subject, and in addition, further substrings from the subject may be picked out by parts of the pattern. Following the usage in Jeffrey Friedl's book, this is called "capturing" in what follows, and the phrase "capturing subpattern" is used for a fragment of a pattern that picks out a substring. PCRE supports several other kinds of parenthesized subpattern that do not cause substrings to be captured.

Captured substrings are returned to the caller via a vector of integers whose address is passed in ovector. The number of elements in the vector is passed in ovecsize, which must be a non-negative number. Note: this argument is NOT the size of ovector in bytes.

The first two-thirds of the vector is used to pass back captured substrings, each substring using a pair of integers. The remaining third of the vector is used as workspace by pcre_exec() while matching capturing subpatterns, and is not available for passing back information. The number passed in ovecsize should always be a multiple of three. If it is not, it is rounded down.

When a match is successful, information about captured substrings is returned in pairs of integers, starting at the beginning of ovector, and continuing up to two-thirds of its length at the most. The first element of each pair is set to the byte offset of the first character in a substring, and the second is set to the byte offset of the first character after the end of a substring. Note: these values are always byte offsets, even in UTF-8 mode. They are not character counts.

The first pair of integers, ovector[0] and ovector[1], identify the portion of the subject string matched by the entire pattern. The next pair is used for the first capturing subpattern, 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, it is used as far as possible (up to two-thirds of its length), and the function returns a value of zero. If neither the actual string matched nor any captured substrings are 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. Thus it is usually advisable to supply an ovector of reasonable size.

There are some cases where zero is returned (indicating vector overflow) when in fact the vector is exactly the right size for the final match. For example, consider the pattern

  (a)(?:(b)c|bd)
If a vector of 6 elements (allowing for only 1 captured substring) is given with subject string "abd", pcre_exec() will try to set the second captured string, thereby recording a vector overflow, before failing to match "c" and backing up to try the second alternative. The zero return, however, does correctly indicate that the maximum number of slots (namely 2) have been filled. In similar cases where there is temporary overflow, but the final number of used slots is actually less than the maximum, a non-zero value is returned.

The pcre_fullinfo() 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 corresponding 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, and the offsets for for the second and third capturing subpatterns (assuming the vector is large enough, of course) are set to -1.

Note: Elements in the first two-thirds of ovector that do not correspond to capturing parentheses in the pattern are never changed. That is, if a pattern contains n capturing parentheses, no more than ovector[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in the first two-thirds) retain whatever values they previously had.

Some convenience functions are provided for extracting the captured substrings as separate strings. These are described below.


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)
The subject string did not match the pattern.
  PCRE_ERROR_NULL           (-2)
Either code or subject was passed as NULL, or ovector was NULL and ovecsize was not zero.
  PCRE_ERROR_BADOPTION      (-3)
An unrecognized bit was set in the options argument.
  PCRE_ERROR_BADMAGIC       (-4)
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 gives when the magic number is not present.
  PCRE_ERROR_UNKNOWN_OPCODE (-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 overwriting of the compiled pattern.
  PCRE_ERROR_NOMEMORY       (-6)
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 memory is automatically freed at the end of matching.

This error is also given if pcre_stack_malloc() fails in pcre_exec(). This can happen only when PCRE has been compiled with --disable-stack-for-recursion.

  PCRE_ERROR_NOSUBSTRING    (-7)
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 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. See the pcrecallout documentation for details.
  PCRE_ERROR_BADUTF8        (-10)
A string that contains an invalid UTF-8 byte sequence was passed as a subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector (ovecsize) is at least 2, the byte offset to the start of the the invalid UTF-8 character is placed in the first element, and a reason code is placed in the second element. The reason codes are listed in the following section. For backward compatibility, if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 character at the end of the subject (reason codes 1 to 5), PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8.
  PCRE_ERROR_BADUTF8_OFFSET (-11)
The UTF-8 byte sequence that was passed as a subject was checked and found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the value of startoffset did not point to the beginning of a UTF-8 character or the end of the subject.
  PCRE_ERROR_PARTIAL        (-12)
The subject string did not match, but it did match partially. See the pcrepartial documentation for details of partial matching.
  PCRE_ERROR_BADPARTIAL     (-13)
This code is no longer in use. It was formerly returned when the PCRE_PARTIAL option was used with a compiled pattern containing items that were not supported for partial matching. From release 8.00 onwards, there are no restrictions on partial matching.
  PCRE_ERROR_INTERNAL       (-14)
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.
  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 description above.
  PCRE_ERROR_BADNEWLINE     (-23)
An invalid combination of PCRE_NEWLINE_xxx options was given.
  PCRE_ERROR_BADOFFSET      (-24)
The value of startoffset was negative or greater than the length of the subject, that is, the value in length.
  PCRE_ERROR_SHORTUTF8      (-25)
This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set. Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but this special error code for PCRE_PARTIAL_HARD precedes the implementation of returned information; it is retained for backwards compatibility.
  PCRE_ERROR_RECURSELOOP    (-26)
This error is returned when pcre_exec() detects a recursion loop within the pattern. Specifically, it means that either the whole pattern or a subpattern has been called recursively for the second time at the same position in the subject string. Some simple patterns that might do this are detected and faulted at compile time, but more complicated cases, in particular mutual recursions between two different subpatterns, cannot be detected until run time.
  PCRE_ERROR_JIT_STACKLIMIT (-27)
This error is returned when a pattern that was successfully studied using a JIT compile option is being matched, but the memory available for the just-in-time processing stack is not large enough. See the pcrejit documentation for more details.
  PCRE_ERROR_BADMODE        (-28)
This error is given if a pattern that was compiled by the 8-bit library is passed to a 16-bit library function, or vice versa.
  PCRE_ERROR_BADENDIANNESS  (-29)
This error is given if a pattern that was compiled and saved is reloaded on a host with different endianness. The utility function pcre_pattern_to_host_byte_order() can be used to convert such a pattern so that it runs on the new host.

Error numbers -16 to -20, -22, and -30 are not used by pcre_exec().


Reason codes for invalid UTF-8 strings

This section applies only to the 8-bit library. The corresponding information for the 16-bit library is given in the pcre16 page.

When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORTUTF8, and the size of the output vector (ovecsize) is at least 2, the offset of the start of the invalid UTF-8 character is placed in the first output vector element (ovector[0]) and a reason code is placed in the second element (ovector[1]). The reason codes are given names in the pcre.h header file:

  PCRE_UTF8_ERR1
  PCRE_UTF8_ERR2
  PCRE_UTF8_ERR3
  PCRE_UTF8_ERR4
  PCRE_UTF8_ERR5
The string ends with a truncated UTF-8 character; the code specifies how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 characters to be no longer than 4 bytes, the encoding scheme (originally defined by RFC 2279) allows for up to 6 bytes, and this is checked first; hence the possibility of 4 or 5 missing bytes.
  PCRE_UTF8_ERR6
  PCRE_UTF8_ERR7
  PCRE_UTF8_ERR8
  PCRE_UTF8_ERR9
  PCRE_UTF8_ERR10
The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of the character do not have the binary value 0b10 (that is, either the most significant bit is 0, or the next bit is 1).
  PCRE_UTF8_ERR11
  PCRE_UTF8_ERR12
A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long; these code points are excluded by RFC 3629.
  PCRE_UTF8_ERR13
A 4-byte character has a value greater than 0x10fff; these code points are excluded by RFC 3629.
  PCRE_UTF8_ERR14
A 3-byte character has a value in the range 0xd800 to 0xdfff; this range of code points are reserved by RFC 3629 for use with UTF-16, and so are excluded from UTF-8.
  PCRE_UTF8_ERR15
  PCRE_UTF8_ERR16
  PCRE_UTF8_ERR17
  PCRE_UTF8_ERR18
  PCRE_UTF8_ERR19
A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes for a value that can be represented by fewer bytes, which is invalid. For example, the two bytes 0xc0, 0xae give the value 0x2e, whose correct coding uses just one byte.
  PCRE_UTF8_ERR20
The two most significant bits of the first byte of a character have the binary value 0b10 (that is, the most significant bit is 1 and the second is 0). Such a byte can only validly occur as the second or subsequent byte of a multi-byte character.
  PCRE_UTF8_ERR21
The first byte of a character has the value 0xfe or 0xff. These values can never occur in a valid UTF-8 string.


EXTRACTING CAPTURED SUBSTRINGS BY NUMBER

int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int buffersize);

int pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr);

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 pcre_copy_substring(), pcre_get_substring(), and pcre_get_substring_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_substring(). 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 functions: 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 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 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_substring(), 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 these error codes:

  PCRE_ERROR_NOMEMORY       (-6)
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 substrings 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 pointer. The yield of the function is zero if all went well, or the error code

  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 empty string. This can be distinguished from a genuine zero-length substring by inspecting the appropriate offset in ovector, which is negative for unset substrings.

The two convenience functions pcre_free_substring() and pcre_free_substring_list() can be used to free the memory returned by a previous call of pcre_get_substring() or pcre_get_substring_list(), respectively. 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 special interface to another programming language that cannot use pcre_free directly; it is for these cases that the functions are provided.


EXTRACTING CAPTURED SUBSTRINGS BY NAME

int pcre_get_stringnumber(const pcre *code, const char *name);

int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int buffersize);

int pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr);

To extract a substring by name, you first have to find associated number. For example, for this pattern

  (a+)b(?<xxx>\d+)...
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 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.

Given the number, you can extract the substring directly, or use one of the functions described in the previous section. For convenience, there are also two functions that do the whole job.

Most of the arguments of pcre_copy_named_substring() and pcre_get_named_substring() are the same as those for the similarly named functions that extract by number. As these are described in the previous section, they are not re-described here. There are just two differences:

First, instead of a substring number, a substring name is given. Second, there is an extra argument, given at the start, which is a pointer to the compiled pattern. This is needed in order to gain access to the name-to-number translation table.

These functions call pcre_get_stringnumber(), and if it succeeds, they then call pcre_copy_substring() or pcre_get_substring(), as appropriate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the behaviour may not be what you want (see the next section).

Warning: If the pattern uses the (?| feature to set up multiple subpatterns with the same number, as described in the section on duplicate subpattern numbers in the pcrepattern page, you cannot use names to distinguish the different subpatterns, because names are not included in the compiled code. The matching process uses only numbers. For this reason, the use of different names for subpatterns of the same number causes an error at compile time.


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. (Duplicate names are always allowed for subpatterns with the same number, created by using the (?| feature. Indeed, if such subpatterns are named, they are required to use the same names.)

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 documentation.

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, PCRE_ERROR_NOSUBSTRING (-7) is returned; no data is returned. The pcre_get_stringnumber() function returns one of the numbers 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 (-7) if there are none. The format of the table is described above in the section entitled Information about a pattern above. Given all the relevant entries for the name, you can extract each of their numbers, and hence the captured data, if any.


FINDING ALL POSSIBLE MATCHES

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 of the callout facility, which is described in the pcrecallout documentation.

What you have to do is to insert a callout right at the end of the pattern. When your callout function is called, extract and save the current 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.


OBTAINING AN ESTIMATE OF STACK USAGE

Matching certain patterns using pcre_exec() can use a lot of process stack, which in certain environments can be rather limited in size. Some users find it helpful to have an estimate of the amount of stack that is used by pcre_exec(), to help them set recursion limits, as described in the pcrestack documentation. The estimate that is output by pcretest when called with the -m and -C options is obtained by calling pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its first five arguments.

Normally, if its first argument is NULL, pcre_exec() immediately returns the negative error code PCRE_ERROR_NULL, but with this special combination of arguments, it returns instead a negative number whose absolute value is the approximate stack frame size in bytes. (A negative number is used so that it is clear that no match has happened.) The value is approximate because in some cases, recursive calls to pcre_exec() occur when there are one or two additional variables on the stack.

If PCRE has been compiled to use the heap instead of the stack for recursion, the value returned is the size of each block that is obtained from the heap.


MATCHING A PATTERN: THE ALTERNATIVE FUNCTION

int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, 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 matching algorithm that scans the subject string just once, and does not backtrack. This has different characteristics to the normal algorithm, and is not compatible 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, and a list of features that pcre_dfa_exec() does not support, see the pcrematching documentation.

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 different 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 keeping track of multiple paths through the pattern tree. More 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():

  int rc;
  int ovector[10];
  int wspace[20];
  rc = pcre_dfa_exec(
    re,             /* result of pcre_compile() */
    NULL,           /* we didn't study the pattern */
    "some string",  /* the subject string */
    11,             /* the length of the subject string */
    0,              /* start at offset 0 in the subject */
    0,              /* default options */
    ovector,        /* vector of integers for substring information */
    10,             /* number of elements (NOT size in bytes) */
    wspace,         /* working space vector */
    20);            /* number of elements (NOT size in bytes) */


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_NEWLINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PARTIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last four of these are exactly the same as for pcre_exec(), so their description is not repeated here.

  PCRE_PARTIAL_HARD
  PCRE_PARTIAL_SOFT
These have the same general effect as they do for pcre_exec(), but the details are slightly different. When PCRE_PARTIAL_HARD is set for pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the subject is reached and there is still at least one matching possibility that requires additional characters. This happens even if some complete matches have also been found. When PCRE_PARTIAL_SOFT is set, 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 possibility. The portion of the string that was inspected when the longest partial match was found is set as the first matching string in both cases. There is a more detailed discussion of partial and multi-segment matching, with examples, in the pcrepartial documentation.
  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 alternative 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() returns a partial match, it is possible to call it again, with additional 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 substring 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, if the pattern

  <.*>
is matched against the string
  This is <something> <something else> <something further> no more
the three matched strings are
  <something>
  <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. In fact, 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 strings is different.)

The strings are returned in reverse order of length; that is, the longest 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. Unlike pcre_exec(), pcre_dfa_exec() can use the entire ovector for returning matched strings.


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 specific to pcre_dfa_exec():

  PCRE_ERROR_DFA_UITEM      (-16)
This return is given if pcre_dfa_exec() encounters an item in the pattern 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 that uses a back reference for the condition, or a test for recursion in a specific group. These are not supported.
  PCRE_ERROR_DFA_UMLIMIT    (-18)
This return is given if pcre_dfa_exec() is called with an extra block that contains a setting of the match_limit or match_limit_recursion fields. This is not supported (these fields are meaningless for DFA matching).
  PCRE_ERROR_DFA_WSSIZE     (-19)
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 should be extremely rare, as a vector of size 1000 is used.
  PCRE_ERROR_DFA_BADRESTART (-30)
When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some plausibility checks are made on the contents of the workspace, which should contain data about the previous partial match. If any of these checks fail, this error is given.


SEE ALSO

pcre16(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematching(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcresample(3), pcrestack(3).


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 17 June 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_copy_substring.html0000644000222100022210000000351611775533017016003 00000000000000 pcre_copy_substring specification

pcre_copy_substring man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int buffersize);

int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, int buffersize);


DESCRIPTION

This is a convenience function for extracting a captured substring into a given buffer. The arguments are:

  subject       Subject that has been successfully matched
  ovector       Offset vector that pcre[16]_exec() used
  stringcount   Value returned by pcre[16]_exec()
  stringnumber  Number of the required substring
  buffer        Buffer to receive the string
  buffersize    Size of buffer
The yield is the length of the string, PCRE_ERROR_NOMEMORY if the buffer was too small, or PCRE_ERROR_NOSUBSTRING if the string number is invalid.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_maketables.html0000644000222100022210000000246111775533017015037 00000000000000 pcre_maketables specification

pcre_maketables man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

const unsigned char *pcre_maketables(void);

const unsigned char *pcre16_maketables(void);


DESCRIPTION

This function builds a set of character tables for character values less than 256. These can be passed to pcre[16]_compile() to override PCRE's internal, built-in tables (which were made by pcre[16]_maketables() when PCRE was compiled). You might want to do this if you are using a non-standard locale. The function yields a pointer to the tables.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrecompat.html0000644000222100022210000002174111775533017014055 00000000000000 pcrecompat specification

pcrecompat man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

DIFFERENCES BETWEEN PCRE AND PERL

This document describes the differences in the ways that PCRE and Perl handle regular expressions. The differences described here are with respect to Perl versions 5.10 and above.

1. PCRE has only a subset of Perl's Unicode support. Details of what it does have are given in the pcreunicode page.

2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do not mean what you might think. For example, (?!a){3} does not assert that the next three characters are not "a". It just asserts that the next character is not "a" three times (in principle: PCRE optimizes this to run the assertion just once). Perl allows repeat quantifiers on other assertions such as \b, but these do not seem to have any use.

3. Capturing subpatterns that occur inside negative lookahead assertions are counted, but their entries in the offsets vector are never set. Perl sets its numerical variables from any such patterns that are matched before the assertion fails to match something (thereby succeeding), but only if the negative lookahead assertion contains just one branch.

4. Though binary zero characters are supported in the subject string, they are not allowed in a pattern string because it is passed as a normal C string, terminated by zero. The escape sequence \0 can be used in the pattern to represent a binary zero.

5. The following Perl escape sequences are not supported: \l, \u, \L, \U, and \N when followed by a character name or Unicode value. (\N on its own, matching a non-newline character, is supported.) In fact these are implemented by Perl's general string-handling and are not part of its pattern matching engine. If any of these are encountered by PCRE, an error is generated by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, \U and \u are interpreted as JavaScript interprets them.

6. The Perl escape sequences \p, \P, and \X are supported only if PCRE is built with Unicode character property support. The properties that can be tested with \p and \P are limited to the general category properties such as Lu and Nd, script names such as Greek or Han, and the derived properties Any and L&. PCRE does support the Cs (surrogate) property, which Perl does not; the Perl documentation says "Because Perl hides the need for the user to understand the internal representation of Unicode characters, there is no need to implement the somewhat messy concept of surrogates."

7. PCRE implements a simpler version of \X than Perl, which changed to make \X match what Unicode calls an "extended grapheme cluster". This is more complicated than an extended Unicode sequence, which is what PCRE matches.

8. PCRE does support the \Q...\E escape for quoting substrings. Characters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they cause variable interpolation (but of course PCRE does not have variables). Note the following examples:

    Pattern            PCRE matches      Perl matches

    \Qabc$xyz\E        abc$xyz           abc followed by the contents of $xyz
    \Qabc\$xyz\E       abc\$xyz          abc\$xyz
    \Qabc\E\$\Qxyz\E   abc$xyz           abc$xyz
The \Q...\E sequence is recognized both inside and outside character classes.

9. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) constructions. However, there is support for recursive patterns. This is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout" feature allows an external function to be called during pattern matching. See the pcrecallout documentation for details.

10. Subpatterns that are called as subroutines (whether or not recursively) are always treated as atomic groups in PCRE. This is like Python, but unlike Perl. Captured values that are set outside a subroutine call can be reference from inside in PCRE, but not in Perl. There is a discussion that explains these differences in more detail in the section on recursion differences from Perl in the pcrepattern page.

11. If any of the backtracking control verbs are used in an assertion or in a subpattern that is called as a subroutine (whether or not recursively), their effect is confined to that subpattern; it does not extend to the surrounding pattern. This is not always the case in Perl. In particular, if (*THEN) is present in a group that is called as a subroutine, its action is limited to that group, even if the group does not contain any | characters. There is one exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a successful positive assertion is passed back when a match succeeds (compare capturing parentheses in assertions). Note that such subpatterns are processed as anchored at the point where they are tested.

12. There are some differences that are concerned with the settings of captured strings when part of a pattern is repeated. For example, matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b".

13. PCRE's handling of duplicate subpattern numbers and duplicate subpattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external table to translate between numbers and names. In particular, a pattern such as (?|(?<a>A)|(?<b)B), where the two capturing parentheses have the same number but different names, is not supported, and causes an error at compile time. If it were allowed, it would not be possible to distinguish which parentheses matched, because both names map to capturing subpattern number 1. To avoid this confusing situation, an error is given at compile time.

14. Perl recognizes comments in some places that PCRE does not, for example, between the ( and ? at the start of a subpattern. If the /x modifier is set, Perl allows white space between ( and ? but PCRE never does, even if the PCRE_EXTENDED option is set.

15. PCRE provides some extensions to the Perl regular expression facilities. Perl 5.10 includes new features that are not in earlier versions of Perl, some of which (such as named parentheses) have been in PCRE for some time. This list is with respect to Perl 5.10:

(a) Although lookbehind assertions in PCRE must match fixed length strings, each alternative branch of a lookbehind assertion can match a different length of string. Perl requires them all to have the same length.

(b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ 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 special meaning is faulted. Otherwise, like Perl, the backslash is quietly ignored. (Perl can be made to issue a warning.)

(d) If PCRE_UNGREEDY is set, the greediness of the repetition quantifiers is inverted, that is, by default they are not greedy, but if followed 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, PCRE_NOTEMPTY_ATSTART, and PCRE_NO_AUTO_CAPTURE options for pcre_exec() have no Perl equivalents.

(g) The \R escape sequence can be restricted to match only CR, LF, or CRLF by the PCRE_BSR_ANYCRLF option.

(h) The callout facility is PCRE-specific.

(i) The partial matching facility is PCRE-specific.

(j) Patterns compiled by PCRE can be saved and re-used at a later time, even on different hosts that have the other endianness. However, this does not apply to optimized data created by the just-in-time compiler.

(k) The alternative matching functions (pcre_dfa_exec() and pcre16_dfa_exec()) match in a different way and are not Perl-compatible.

(l) PCRE recognizes some special sequences such as (*CR) at the start of a pattern that set overall options that cannot be changed within the pattern.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 01 June 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_jit_stack_alloc.html0000644000222100022210000000306611775533017016056 00000000000000 pcre_jit_stack_alloc specification

pcre_jit_stack_alloc man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

pcre_jit_stack *pcre_jit_stack_alloc(int startsize, int maxsize);

pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize);


DESCRIPTION

This function is used to create a stack for use by the code compiled by the JIT optimization of pcre[16]_study(). The arguments are a starting size for the stack, and a maximum size to which it is allowed to grow. The result can be passed to the JIT run-time code by pcre[16]_assign_jit_stack(), or that function can set up a callback for obtaining a stack. A maximum stack size of 512K to 1M should be more than enough for any pattern. For more details, see the pcrejit page.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_compile2.html0000644000222100022210000001016511775533017014441 00000000000000 pcre_compile2 specification

pcre_compile2 man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

pcre *pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr);

pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr);


DESCRIPTION

This function compiles a regular expression into an internal form. It is the same as pcre[16]_compile(), except for the addition of the errorcodeptr argument. The arguments are:

  pattern       A zero-terminated string containing the
                  regular expression to be compiled
  options       Zero or more option bits
  errorcodeptr  Where to put an error code
  errptr        Where to put an error message
  erroffset     Offset in pattern where error was found
  tableptr      Pointer to character tables, or NULL to
                  use the built-in default
The option bits are:
  PCRE_ANCHORED           Force pattern anchoring
  PCRE_AUTO_CALLOUT       Compile automatic callouts
  PCRE_BSR_ANYCRLF        \R matches only CR, LF, or CRLF
  PCRE_BSR_UNICODE        \R matches all Unicode line endings
  PCRE_CASELESS           Do caseless matching
  PCRE_DOLLAR_ENDONLY     $ not to match newline at end
  PCRE_DOTALL             . matches anything including NL
  PCRE_DUPNAMES           Allow duplicate names for subpatterns
  PCRE_EXTENDED           Ignore white space and # comments
  PCRE_EXTRA              PCRE extra features
                            (not much use currently)
  PCRE_FIRSTLINE          Force matching to be before newline
  PCRE_JAVASCRIPT_COMPAT  JavaScript compatibility
  PCRE_MULTILINE          ^ and $ match newlines within data
  PCRE_NEWLINE_ANY        Recognize any Unicode newline sequence
  PCRE_NEWLINE_ANYCRLF    Recognize CR, LF, and CRLF as newline
                            sequences
  PCRE_NEWLINE_CR         Set CR as the newline sequence
  PCRE_NEWLINE_CRLF       Set CRLF as the newline sequence
  PCRE_NEWLINE_LF         Set LF as the newline sequence
  PCRE_NO_AUTO_CAPTURE    Disable numbered capturing paren-
                            theses (named ones available)
  PCRE_NO_UTF16_CHECK     Do not check the pattern for UTF-16
                            validity (only relevant if
                            PCRE_UTF16 is set)
  PCRE_NO_UTF8_CHECK      Do not check the pattern for UTF-8
                            validity (only relevant if
                            PCRE_UTF8 is set)
  PCRE_UCP                Use Unicode properties for \d, \w, etc.
  PCRE_UNGREEDY           Invert greediness of quantifiers
  PCRE_UTF16              Run pcre16_compile() in UTF-16 mode
  PCRE_UTF8               Run pcre_compile() in UTF-8 mode
PCRE must be built with UTF support in order to use PCRE_UTF8/16 and PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.

The yield of the function is a pointer to a private data structure that contains the compiled pattern, or NULL if an error was detected. Note that compiling regular expressions with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/index.html0000644000222100022210000001570511775533020013024 00000000000000 PCRE specification

Perl-compatible Regular Expressions (PCRE)

The HTML documentation for PCRE comprises the following pages:

pcre   Introductory page
pcre16   Discussion of the 16-bit PCRE library
pcre-config   Information about the installation configuration
pcreapi   PCRE's native API
pcrebuild   Options for building PCRE
pcrecallout   The callout facility
pcrecompat   Compability with Perl
pcrecpp   The C++ wrapper for the PCRE library
pcredemo   A demonstration C program that uses the PCRE library
pcregrep   The pcregrep command
pcrejit   Discussion of the just-in-time optimization support
pcrelimits   Details of size and other limits
pcrematching   Discussion of the two matching algorithms
pcrepartial   Using PCRE for partial matching
pcrepattern   Specification of the regular expressions supported by PCRE
pcreperform   Some comments on performance
pcreposix   The POSIX API to the PCRE library
pcreprecompile   How to save and re-use compiled patterns
pcresample   Discussion of the pcredemo program
pcrestack   Discussion of PCRE's stack usage
pcresyntax   Syntax quick-reference summary
pcretest   The pcretest command for testing PCRE
pcreunicode   Discussion of Unicode and UTF-8/UTF-16 support

There are also individual pages that summarize the interface for each function in the library. There is a single page for each pair of 8-bit/16-bit functions.

pcre_assign_jit_stack   Assign stack for JIT matching
pcre_compile   Compile a regular expression
pcre_compile2   Compile a regular expression (alternate interface)
pcre_config   Show build-time configuration options
pcre_copy_named_substring   Extract named substring into given buffer
pcre_copy_substring   Extract numbered substring into given buffer
pcre_dfa_exec   Match a compiled pattern to a subject string (DFA algorithm; not Perl compatible)
pcre_free_study   Free study data
pcre_exec   Match a compiled pattern to a subject string (Perl compatible)
pcre_free_substring   Free extracted substring
pcre_free_substring_list   Free list of extracted substrings
pcre_fullinfo   Extract information about a pattern
pcre_get_named_substring   Extract named substring into new memory
pcre_get_stringnumber   Convert captured string name to number
pcre_get_substring   Extract numbered substring into new memory
pcre_get_substring_list   Extract all substrings into new memory
pcre_info   Obsolete information extraction function
pcre_jit_stack_alloc   Create a stack for JIT matching
pcre_jit_stack_free   Free a JIT matching stack
pcre_maketables   Build character tables in current locale
pcre_pattern_to_host_byte_order   Convert compiled pattern to host byte order if necessary
pcre_refcount   Maintain reference count in compiled pattern
pcre_study   Study a compiled pattern
pcre_utf16_to_host_byte_order   Convert UTF-16 string to host byte order if necessary
pcre_version   Return PCRE version and release date
pcre-8.31/doc/html/pcre_pattern_to_host_byte_order.html0000644000222100022210000000340111775533017020354 00000000000000 pcre_pattern_to_host_byte_order specification

pcre_pattern_to_host_byte_order man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_pattern_to_host_byte_order(pcre *code, pcre_extra *extra, const unsigned char *tables);

int pcre16_pattern_to_host_byte_order(pcre16 *code, pcre16_extra *extra, const unsigned char *tables);


DESCRIPTION

This function ensures that the bytes in 2-byte and 4-byte values in a compiled pattern are in the correct order for the current host. It is useful when a pattern that has been compiled on one host is transferred to another that might have different endianness. The arguments are:

  code         A compiled regular expression
  extra        Points to an associated pcre[16]_extra structure,
                 or is NULL
  tables       Pointer to character tables, or NULL to
                 set the built-in default
The result is 0 for success, a negative PCRE_ERROR_xxx value otherwise.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_get_stringnumber.html0000644000222100022210000000315611775533017016307 00000000000000 pcre_get_stringnumber specification

pcre_get_stringnumber man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_get_stringnumber(const pcre *code, const char *name);

int pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 name);


DESCRIPTION

This convenience function finds the number of a named substring capturing parenthesis in a compiled pattern. Its arguments are:

  code    Compiled regular expression
  name    Name whose number is required
The yield of the function is the number of the parenthesis if the name is found, or PCRE_ERROR_NOSUBSTRING otherwise. When duplicate names are allowed (PCRE_DUPNAMES is set), it is not defined which of the numbers is returned by pcre[16]_get_stringnumber(). You can obtain the complete list by calling pcre[16]_get_stringtable_entries().

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_utf16_to_host_byte_order.html0000644000222100022210000000374711775533017017661 00000000000000 pcre_utf16_to_host_byte_order specification

pcre_utf16_to_host_byte_order man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input, int length, int *host_byte_order, int keep_boms);


DESCRIPTION

This function, which exists only in the 16-bit library, converts a UTF-16 string to the correct order for the current host, taking account of any byte order marks (BOMs) within the string. Its arguments are:

  output           pointer to output buffer, may be the same as input
  input            pointer to input buffer
  length           number of 16-bit units in the input, or negative for
                     a zero-terminated string
  host_byte_order  a NULL value or a non-zero value pointed to means
                     start in host byte order
  keep_boms        if non-zero, BOMs are copied to the output string
The result of the function is the number of 16-bit units placed into the output buffer, including the zero terminator if the string was zero-terminated.

If host_byte_order is not NULL, it is set to indicate the byte order that is current at the end of the string.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_refcount.html0000644000222100022210000000252511775533017014555 00000000000000 pcre_refcount specification

pcre_refcount man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_refcount(pcre *code, int adjust);

int pcre16_refcount(pcre16 *code, int adjust);


DESCRIPTION

This function is used to maintain a reference count inside a data block that contains a compiled pattern. Its arguments are:

  code                      Compiled regular expression
  adjust                    Adjustment to reference value
The yield of the function is the adjusted reference value, which is constrained to lie between 0 and 65535.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_get_stringtable_entries.html0000644000222100022210000000352211775533017017634 00000000000000 pcre_get_stringtable_entries specification

pcre_get_stringtable_entries man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_get_stringtable_entries(const pcre *code, const char *name, char **first, char **last);

int pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last);


DESCRIPTION

This convenience function finds, for a compiled pattern, the first and last entries for a given name in the table that translates capturing parenthesis names into numbers. When names are required to be unique (PCRE_DUPNAMES is not set), it is usually easier to use pcre[16]_get_stringnumber() instead.

  code    Compiled regular expression
  name    Name whose entries required
  first   Where to return a pointer to the first entry
  last    Where to return a pointer to the last entry
The yield of the function is the length of each entry, or PCRE_ERROR_NOSUBSTRING if none are found.

There is a complete description of the PCRE native API, including the format of the table entries, in the pcreapi page, and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrecpp.html0000644000222100022210000003406111775533020013345 00000000000000 pcrecpp specification

pcrecpp man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


SYNOPSIS OF C++ WRAPPER

#include <pcrecpp.h>


DESCRIPTION

The C++ wrapper for PCRE was provided by Google Inc. Some additional functionality was added by Giuseppe Maxia. This brief man page was constructed from the notes in the pcrecpp.h file, which should be consulted for further details. Note that the C++ wrapper supports only the original 8-bit PCRE library. There is no 16-bit support at present.


MATCHING INTERFACE

The "FullMatch" operation checks that supplied text matches a supplied pattern exactly. If pointer arguments are supplied, it copies matched sub-strings that match sub-patterns into them.

  Example: successful match
     pcrecpp::RE re("h.*o");
     re.FullMatch("hello");

  Example: unsuccessful match (requires full match):
     pcrecpp::RE re("e");
     !re.FullMatch("hello");

  Example: creating a temporary RE object:
     pcrecpp::RE("h.*o").FullMatch("hello");
You can pass in a "const char*" or a "string" for "text". The examples below tend to use a const char*. You can, as in the different examples above, store the RE object explicitly in a variable or use a temporary RE object. The examples below use one mode or the other arbitrarily. Either could correctly be used for any of these examples.

You must supply extra pointer arguments to extract matched subpieces.

  Example: extracts "ruby" into "s" and 1234 into "i"
     int i;
     string s;
     pcrecpp::RE re("(\\w+):(\\d+)");
     re.FullMatch("ruby:1234", &s, &i);

  Example: does not try to extract any extra sub-patterns
     re.FullMatch("ruby:1234", &s);

  Example: does not try to extract into NULL
     re.FullMatch("ruby:1234", NULL, &i);

  Example: integer overflow causes failure
     !re.FullMatch("ruby:1234567891234", NULL, &i);

  Example: fails because there aren't enough sub-patterns:
     !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s);

  Example: fails because string cannot be stored in integer
     !pcrecpp::RE("(.*)").FullMatch("ruby", &i);
The provided pointer arguments can be pointers to any scalar numeric type, or one of:
   string        (matched piece is copied to string)
   StringPiece   (StringPiece is mutated to point to matched piece)
   T             (where "bool T::ParseFrom(const char*, int)" exists)
   NULL          (the corresponding matched sub-pattern is not copied)
The function returns true iff all of the following conditions are satisfied:
  a. "text" matches "pattern" exactly;

  b. The number of matched sub-patterns is >= number of supplied
     pointers;

  c. The "i"th argument has a suitable type for holding the
     string captured as the "i"th sub-pattern. If you pass in
     void * NULL for the "i"th argument, or a non-void * NULL
     of the correct type, or pass fewer arguments than the
     number of sub-patterns, "i"th captured sub-pattern is
     ignored.
CAVEAT: An optional sub-pattern that does not exist in the matched string is assigned the empty string. Therefore, the following will return false (because the empty string is not a valid number):
   int number;
   pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number);
The matching interface supports at most 16 arguments per call. If you need more, consider using the more general interface pcrecpp::RE::DoMatch. See pcrecpp.h for the signature for DoMatch.

NOTE: Do not use no_arg, which is used internally to mark the end of a list of optional arguments, as a placeholder for missing arguments, as this can lead to segfaults.


QUOTING METACHARACTERS

You can use the "QuoteMeta" operation to insert backslashes before all potentially meaningful characters in a string. The returned string, used as a regular expression, will exactly match the original string.

  Example:
     string quoted = RE::QuoteMeta(unquoted);
Note that it's legal to escape a character even if it has no special meaning in a regular expression -- so this function does that. (This also makes it identical to the perl function of the same name; see "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes "1\.5\-2\.0\?".


PARTIAL MATCHES

You can use the "PartialMatch" operation when you want the pattern to match any substring of the text.

  Example: simple search for a string:
     pcrecpp::RE("ell").PartialMatch("hello");

  Example: find first number in a string:
     int number;
     pcrecpp::RE re("(\\d+)");
     re.PartialMatch("x*100 + 20", &number);
     assert(number == 100);


UTF-8 AND THE MATCHING INTERFACE

By default, pattern and text are plain text, one byte per character. The UTF8 flag, passed to the constructor, causes both pattern and string to be treated as UTF-8 text, still a byte stream but potentially multiple bytes per character. In practice, the text is likelier to be UTF-8 than the pattern, but the match returned may depend on the UTF8 flag, so always use it when matching UTF8 text. For example, "." will match one byte normally but with UTF8 set may match up to three bytes of a multi-byte character.

  Example:
     pcrecpp::RE_Options options;
     options.set_utf8();
     pcrecpp::RE re(utf8_pattern, options);
     re.FullMatch(utf8_string);

  Example: using the convenience function UTF8():
     pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8());
     re.FullMatch(utf8_string);
NOTE: The UTF8 flag is ignored if pcre was not configured with the
      --enable-utf8 flag.


PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE

PCRE defines some modifiers to change the behavior of the regular expression engine. The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle to pass such modifiers to a RE class. Currently, the following modifiers are supported:

   modifier              description               Perl corresponding

   PCRE_CASELESS         case insensitive match      /i
   PCRE_MULTILINE        multiple lines match        /m
   PCRE_DOTALL           dot matches newlines        /s
   PCRE_DOLLAR_ENDONLY   $ matches only at end       N/A
   PCRE_EXTRA            strict escape parsing       N/A
   PCRE_EXTENDED         ignore white spaces         /x
   PCRE_UTF8             handles UTF8 chars          built-in
   PCRE_UNGREEDY         reverses * and *?           N/A
   PCRE_NO_AUTO_CAPTURE  disables capturing parens   N/A (*)
(*) Both Perl and PCRE allow non capturing parentheses by means of the "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not capture, while (ab|cd) does.

For a full account on how each modifier works, please check the PCRE API reference page.

For each modifier, there are two member functions whose name is made out of the modifier in lowercase, without the "PCRE_" prefix. For instance, PCRE_CASELESS is handled by

  bool caseless()
which returns true if the modifier is set, and
  RE_Options & set_caseless(bool)
which sets or unsets the modifier. Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the set_match_limit() and match_limit() member functions. Setting match_limit to a non-zero value will limit the execution of pcre to keep it from doing bad things like blowing the stack or taking an eternity to return a result. A value of 5000 is good enough to stop stack blowup in a 2MB thread stack. Setting match_limit to zero disables match limiting. Alternatively, you can call match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much PCRE recurses. match_limit() limits the number of matches PCRE does; match_limit_recursion() limits the depth of internal recursion, and therefore the amount of stack that is used.

Normally, to pass one or more modifiers to a RE class, you declare a RE_Options object, set the appropriate options, and pass this object to a RE constructor. Example:

   RE_Options opt;
   opt.set_caseless(true);
   if (RE("HELLO", opt).PartialMatch("hello world")) ...
RE_options has two constructors. The default constructor takes no arguments and creates a set of flags that are off by default. The optional parameter option_flags is to facilitate transfer of legacy code from C programs. This lets you do
   RE(pattern,
     RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str);
However, new code is better off doing
   RE(pattern,
     RE_Options().set_caseless(true).set_multiline(true))
       .PartialMatch(str);
If you are going to pass one of the most used modifiers, there are some convenience functions that return a RE_Options class with the appropriate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(), and EXTENDED().

If you need to set several options at once, and you don't want to go through the pains of declaring a RE_Options object and setting several options, there is a parallel method that give you such ability on the fly. You can concatenate several set_xxxxx() member functions, since each of them returns a reference to its class object. For example, to pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one statement, you may write:

   RE(" ^ xyz \\s+ .* blah$",
     RE_Options()
       .set_caseless(true)
       .set_extended(true)
       .set_multiline(true)).PartialMatch(sometext);


SCANNING TEXT INCREMENTALLY

The "Consume" operation may be useful if you want to repeatedly match regular expressions at the front of a string and skip over them as they match. This requires use of the "StringPiece" type, which represents a sub-range of a real string. Like RE, StringPiece is defined in the pcrecpp namespace.

  Example: read lines of the form "var = value" from a string.
     string contents = ...;                 // Fill string somehow
     pcrecpp::StringPiece input(contents);  // Wrap in a StringPiece

     string var;
     int value;
     pcrecpp::RE re("(\\w+) = (\\d+)\n");
     while (re.Consume(&input, &var, &value)) {
       ...;
     }
Each successful call to "Consume" will set "var/value", and also advance "input" so it points past the matched text.

The "FindAndConsume" operation is similar to "Consume" but does not anchor your match at the beginning of the string. For example, you could extract all words from a string by repeatedly calling

  pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word)


PARSING HEX/OCTAL/C-RADIX NUMBERS

By default, if you pass a pointer to a numeric value, the corresponding text is interpreted as a base-10 number. You can instead wrap the pointer with a call to one of the operators Hex(), Octal(), or CRadix() to interpret the text in another base. The CRadix operator interprets C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to base-10.

  Example:
    int a, b, c, d;
    pcrecpp::RE re("(.*) (.*) (.*) (.*)");
    re.FullMatch("100 40 0100 0x40",
                 pcrecpp::Octal(&a), pcrecpp::Hex(&b),
                 pcrecpp::CRadix(&c), pcrecpp::CRadix(&d));
will leave 64 in a, b, c, and d.


REPLACING PARTS OF STRINGS

You can replace the first match of "pattern" in "str" with "rewrite". Within "rewrite", backslash-escaped digits (\1 to \9) can be used to insert text matching corresponding parenthesized group from the pattern. \0 in "rewrite" refers to the entire matching text. For example:

  string s = "yabba dabba doo";
  pcrecpp::RE("b+").Replace("d", &s);
will leave "s" containing "yada dabba doo". The result is true if the pattern matches and a replacement occurs, false otherwise.

GlobalReplace is like Replace except that it replaces all occurrences of the pattern in the string with the rewrite. Replacements are not subject to re-matching. For example:

  string s = "yabba dabba doo";
  pcrecpp::RE("b+").GlobalReplace("d", &s);
will leave "s" containing "yada dada doo". It returns the number of replacements made.

Extract is like Replace, except that if the pattern matches, "rewrite" is copied into "out" (an additional argument) with substitutions. The non-matching portions of "text" are ignored. Returns true iff a match occurred and the extraction happened successfully; if no match occurs, the string is left unaffected.


AUTHOR

The C++ wrapper was contributed by Google Inc.
Copyright © 2007 Google Inc.


REVISION

Last updated: 08 January 2012

Return to the PCRE index page.

pcre-8.31/doc/html/pcredemo.html0000644000222100022210000003750011775533020013510 00000000000000 pcredemo specification

pcredemo man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

/*************************************************
*           PCRE DEMONSTRATION PROGRAM           *
*************************************************/

/* This is a demonstration program to illustrate the most straightforward ways
of calling the PCRE regular expression library from a C program. See the
pcresample documentation for a short discussion ("man pcresample" if you have
the PCRE man pages installed).

In Unix-like environments, if PCRE is installed in your standard system
libraries, you should be able to compile this program using this command:

gcc -Wall pcredemo.c -lpcre -o pcredemo

If PCRE is not installed in a standard place, it is likely to be installed with
support for the pkg-config mechanism. If you have pkg-config, you can compile
this program using this command:

gcc -Wall pcredemo.c `pkg-config --cflags --libs libpcre` -o pcredemo

If you do not have pkg-config, you may have to use this:

gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \
  -R/usr/local/lib -lpcre -o pcredemo

Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and
library files for PCRE are installed on your system. Only some operating
systems (e.g. Solaris) use the -R option.

Building under Windows:

If you want to statically link this program against a non-dll .a file, you must
define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc() and
pcre_free() exported functions will be declared __declspec(dllimport), with
unwanted results. So in this environment, uncomment the following line. */

/* #define PCRE_STATIC */

#include <stdio.h>
#include <string.h>
#include <pcre.h>

#define OVECCOUNT 30    /* should be a multiple of 3 */


int main(int argc, char **argv)
{
pcre *re;
const char *error;
char *pattern;
char *subject;
unsigned char *name_table;
unsigned int option_bits;
int erroffset;
int find_all;
int crlf_is_newline;
int namecount;
int name_entry_size;
int ovector[OVECCOUNT];
int subject_length;
int rc, i;
int utf8;


/**************************************************************************
* First, sort out the command line. There is only one possible option at  *
* the moment, "-g" to request repeated matching to find all occurrences,  *
* like Perl's /g option. We set the variable find_all to a non-zero value *
* if the -g option is present. Apart from that, there must be exactly two *
* arguments.                                                              *
**************************************************************************/

find_all = 0;
for (i = 1; i < argc; i++)
  {
  if (strcmp(argv[i], "-g") == 0) find_all = 1;
    else break;
  }

/* After the options, we require exactly two arguments, which are the pattern,
and the subject string. */

if (argc - i != 2)
  {
  printf("Two arguments required: a regex and a subject string\n");
  return 1;
  }

pattern = argv[i];
subject = argv[i+1];
subject_length = (int)strlen(subject);


/*************************************************************************
* Now we are going to compile the regular expression pattern, and handle *
* and errors that are detected.                                          *
*************************************************************************/

re = pcre_compile(
  pattern,              /* the pattern */
  0,                    /* default options */
  &error,               /* for error message */
  &erroffset,           /* for error offset */
  NULL);                /* use default character tables */

/* Compilation failed: print the error message and exit */

if (re == NULL)
  {
  printf("PCRE compilation failed at offset %d: %s\n", erroffset, error);
  return 1;
  }


/*************************************************************************
* If the compilation succeeded, we call PCRE again, in order to do a     *
* pattern match against the subject string. This does just ONE match. If *
* further matching is needed, it will be done below.                     *
*************************************************************************/

rc = pcre_exec(
  re,                   /* the compiled pattern */
  NULL,                 /* no extra data - we didn't study the pattern */
  subject,              /* the subject string */
  subject_length,       /* the length of the subject */
  0,                    /* start at offset 0 in the subject */
  0,                    /* default options */
  ovector,              /* output vector for substring information */
  OVECCOUNT);           /* number of elements in the output vector */

/* Matching failed: handle error cases */

if (rc < 0)
  {
  switch(rc)
    {
    case PCRE_ERROR_NOMATCH: printf("No match\n"); break;
    /*
    Handle other special cases if you like
    */
    default: printf("Matching error %d\n", rc); break;
    }
  pcre_free(re);     /* Release memory used for the compiled pattern */
  return 1;
  }

/* Match succeded */

printf("\nMatch succeeded at offset %d\n", ovector[0]);


/*************************************************************************
* We have found the first match within the subject string. If the output *
* vector wasn't big enough, say so. Then output any substrings that were *
* captured.                                                              *
*************************************************************************/

/* The output vector wasn't big enough */

if (rc == 0)
  {
  rc = OVECCOUNT/3;
  printf("ovector only has room for %d captured substrings\n", rc - 1);
  }

/* Show substrings stored in the output vector by number. Obviously, in a real
application you might want to do things other than print them. */

for (i = 0; i < rc; i++)
  {
  char *substring_start = subject + ovector[2*i];
  int substring_length = ovector[2*i+1] - ovector[2*i];
  printf("%2d: %.*s\n", i, substring_length, substring_start);
  }


/**************************************************************************
* That concludes the basic part of this demonstration program. We have    *
* compiled a pattern, and performed a single match. The code that follows *
* shows first how to access named substrings, and then how to code for    *
* repeated matches on the same subject.                                   *
**************************************************************************/

/* See if there are any named substrings, and if so, show them by name. First
we have to extract the count of named parentheses from the pattern. */

(void)pcre_fullinfo(
  re,                   /* the compiled pattern */
  NULL,                 /* no extra data - we didn't study the pattern */
  PCRE_INFO_NAMECOUNT,  /* number of named substrings */
  &namecount);          /* where to put the answer */

if (namecount <= 0) printf("No named substrings\n"); else
  {
  unsigned char *tabptr;
  printf("Named substrings\n");

  /* Before we can access the substrings, we must extract the table for
  translating names to numbers, and the size of each entry in the table. */

  (void)pcre_fullinfo(
    re,                       /* the compiled pattern */
    NULL,                     /* no extra data - we didn't study the pattern */
    PCRE_INFO_NAMETABLE,      /* address of the table */
    &name_table);             /* where to put the answer */

  (void)pcre_fullinfo(
    re,                       /* the compiled pattern */
    NULL,                     /* no extra data - we didn't study the pattern */
    PCRE_INFO_NAMEENTRYSIZE,  /* size of each entry in the table */
    &name_entry_size);        /* where to put the answer */

  /* Now we can scan the table and, for each entry, print the number, the name,
  and the substring itself. */

  tabptr = name_table;
  for (i = 0; i < namecount; i++)
    {
    int n = (tabptr[0] << 8) | tabptr[1];
    printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,
      ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]);
    tabptr += name_entry_size;
    }
  }


/*************************************************************************
* If the "-g" option was given on the command line, we want to continue  *
* to search for additional matches in the subject string, in a similar   *
* way to the /g option in Perl. This turns out to be trickier than you   *
* might think because of the possibility of matching an empty string.    *
* What happens is as follows:                                            *
*                                                                        *
* If the previous match was NOT for an empty string, we can just start   *
* the next match at the end of the previous one.                         *
*                                                                        *
* If the previous match WAS for an empty string, we can't do that, as it *
* would lead to an infinite loop. Instead, a special call of pcre_exec() *
* is made with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED flags set.    *
* The first of these tells PCRE that an empty string at the start of the *
* subject is not a valid match; other possibilities must be tried. The   *
* second flag restricts PCRE to one match attempt at the initial string  *
* position. If this match succeeds, an alternative to the empty string   *
* match has been found, and we can print it and proceed round the loop,  *
* advancing by the length of whatever was found. If this match does not  *
* succeed, we still stay in the loop, advancing by just one character.   *
* In UTF-8 mode, which can be set by (*UTF8) in the pattern, this may be *
* more than one byte.                                                    *
*                                                                        *
* However, there is a complication concerned with newlines. When the     *
* newline convention is such that CRLF is a valid newline, we must       *
* advance by two characters rather than one. The newline convention can  *
* be set in the regex by (*CR), etc.; if not, we must find the default.  *
*************************************************************************/

if (!find_all)     /* Check for -g */
  {
  pcre_free(re);   /* Release the memory used for the compiled pattern */
  return 0;        /* Finish unless -g was given */
  }

/* Before running the loop, check for UTF-8 and whether CRLF is a valid newline
sequence. First, find the options with which the regex was compiled; extract
the UTF-8 state, and mask off all but the newline options. */

(void)pcre_fullinfo(re, NULL, PCRE_INFO_OPTIONS, &option_bits);
utf8 = option_bits & PCRE_UTF8;
option_bits &= PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_CRLF|
               PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF;

/* If no newline options were set, find the default newline convention from the
build configuration. */

if (option_bits == 0)
  {
  int d;
  (void)pcre_config(PCRE_CONFIG_NEWLINE, &d);
  /* Note that these values are always the ASCII ones, even in
  EBCDIC environments. CR = 13, NL = 10. */
  option_bits = (d == 13)? PCRE_NEWLINE_CR :
          (d == 10)? PCRE_NEWLINE_LF :
          (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF :
          (d == -2)? PCRE_NEWLINE_ANYCRLF :
          (d == -1)? PCRE_NEWLINE_ANY : 0;
  }

/* See if CRLF is a valid newline sequence. */

crlf_is_newline =
     option_bits == PCRE_NEWLINE_ANY ||
     option_bits == PCRE_NEWLINE_CRLF ||
     option_bits == PCRE_NEWLINE_ANYCRLF;

/* Loop for second and subsequent matches */

for (;;)
  {
  int options = 0;                 /* Normally no options */
  int start_offset = ovector[1];   /* Start at end of previous match */

  /* If the previous match was for an empty string, we are finished if we are
  at the end of the subject. Otherwise, arrange to run another match at the
  same point to see if a non-empty match can be found. */

  if (ovector[0] == ovector[1])
    {
    if (ovector[0] == subject_length) break;
    options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;
    }

  /* Run the next matching operation */

  rc = pcre_exec(
    re,                   /* the compiled pattern */
    NULL,                 /* no extra data - we didn't study the pattern */
    subject,              /* the subject string */
    subject_length,       /* the length of the subject */
    start_offset,         /* starting offset in the subject */
    options,              /* options */
    ovector,              /* output vector for substring information */
    OVECCOUNT);           /* number of elements in the output vector */

  /* This time, a result of NOMATCH isn't an error. If the value in "options"
  is zero, it just means we have found all possible matches, so the loop ends.
  Otherwise, it means we have failed to find a non-empty-string match at a
  point where there was a previous empty-string match. In this case, we do what
  Perl does: advance the matching position by one character, and continue. We
  do this by setting the "end of previous match" offset, because that is picked
  up at the top of the loop as the point at which to start again.

  There are two complications: (a) When CRLF is a valid newline sequence, and
  the current position is just before it, advance by an extra byte. (b)
  Otherwise we must ensure that we skip an entire UTF-8 character if we are in
  UTF-8 mode. */

  if (rc == PCRE_ERROR_NOMATCH)
    {
    if (options == 0) break;                    /* All matches found */
    ovector[1] = start_offset + 1;              /* Advance one byte */
    if (crlf_is_newline &&                      /* If CRLF is newline & */
        start_offset < subject_length - 1 &&    /* we are at CRLF, */
        subject[start_offset] == '\r' &&
        subject[start_offset + 1] == '\n')
      ovector[1] += 1;                          /* Advance by one more. */
    else if (utf8)                              /* Otherwise, ensure we */
      {                                         /* advance a whole UTF-8 */
      while (ovector[1] < subject_length)       /* character. */
        {
        if ((subject[ovector[1]] & 0xc0) != 0x80) break;
        ovector[1] += 1;
        }
      }
    continue;    /* Go round the loop again */
    }

  /* Other matching errors are not recoverable. */

  if (rc < 0)
    {
    printf("Matching error %d\n", rc);
    pcre_free(re);    /* Release memory used for the compiled pattern */
    return 1;
    }

  /* Match succeded */

  printf("\nMatch succeeded again at offset %d\n", ovector[0]);

  /* The match succeeded, but the output vector wasn't big enough. */

  if (rc == 0)
    {
    rc = OVECCOUNT/3;
    printf("ovector only has room for %d captured substrings\n", rc - 1);
    }

  /* As before, show substrings stored in the output vector by number, and then
  also any named substrings. */

  for (i = 0; i < rc; i++)
    {
    char *substring_start = subject + ovector[2*i];
    int substring_length = ovector[2*i+1] - ovector[2*i];
    printf("%2d: %.*s\n", i, substring_length, substring_start);
    }

  if (namecount <= 0) printf("No named substrings\n"); else
    {
    unsigned char *tabptr = name_table;
    printf("Named substrings\n");
    for (i = 0; i < namecount; i++)
      {
      int n = (tabptr[0] << 8) | tabptr[1];
      printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,
        ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]);
      tabptr += name_entry_size;
      }
    }
  }      /* End of loop to find second and subsequent matches */

printf("\n");
pcre_free(re);       /* Release memory used for the compiled pattern */
return 0;
}

/* End of pcredemo.c */

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_get_substring_list.html0000644000222100022210000000373411775533017016645 00000000000000 pcre_get_substring_list specification

pcre_get_substring_list man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr);

int pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 **listptr);


DESCRIPTION

This is a convenience function for extracting a list of all the captured substrings. The arguments are:

  subject       Subject that has been successfully matched
  ovector       Offset vector that pcre[16]_exec used
  stringcount   Value returned by pcre[16]_exec
  listptr       Where to put a pointer to the list
The memory in which the substrings and the list are placed is obtained by calling pcre[16]_malloc(). The convenience function pcre[16]_free_substring_list() can be used to free it when it is no longer needed. A pointer to a list of pointers is put in the variable whose address is in listptr. The list is terminated by a NULL pointer. The yield of the function is zero on success or PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcresyntax.html0000644000222100022210000003561111775533020014113 00000000000000 pcresyntax specification

pcresyntax man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


PCRE REGULAR EXPRESSION SYNTAX SUMMARY

The full syntax and semantics of the regular expressions that are supported by PCRE are described in the pcrepattern documentation. This document contains a quick-reference summary of the syntax.


QUOTING

  \x         where x is non-alphanumeric is a literal x
  \Q...\E    treat enclosed characters as literal


CHARACTERS

  \a         alarm, that is, the BEL character (hex 07)
  \cx        "control-x", where x is any ASCII character
  \e         escape (hex 1B)
  \f         form feed (hex 0C)
  \n         newline (hex 0A)
  \r         carriage return (hex 0D)
  \t         tab (hex 09)
  \ddd       character with octal code ddd, or backreference
  \xhh       character with hex code hh
  \x{hhh..}  character with hex code hhh..


CHARACTER TYPES

  .          any character except newline;
               in dotall mode, any character whatsoever
  \C         one data unit, even in UTF mode (best avoided)
  \d         a decimal digit
  \D         a character that is not a decimal digit
  \h         a horizontal white space character
  \H         a character that is not a horizontal white space character
  \N         a character that is not a newline
  \p{xx}     a character with the xx property
  \P{xx}     a character without the xx property
  \R         a newline sequence
  \s         a white space character
  \S         a character that is not a white space character
  \v         a vertical white space character
  \V         a character that is not a vertical white space character
  \w         a "word" character
  \W         a "non-word" character
  \X         an extended Unicode sequence
In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII characters, even in a UTF mode. However, this can be changed by setting the PCRE_UCP option.


GENERAL CATEGORY PROPERTIES FOR \p and \P

  C          Other
  Cc         Control
  Cf         Format
  Cn         Unassigned
  Co         Private use
  Cs         Surrogate

  L          Letter
  Ll         Lower case letter
  Lm         Modifier letter
  Lo         Other letter
  Lt         Title case letter
  Lu         Upper case letter
  L&         Ll, Lu, or Lt

  M          Mark
  Mc         Spacing mark
  Me         Enclosing mark
  Mn         Non-spacing mark

  N          Number
  Nd         Decimal number
  Nl         Letter number
  No         Other number

  P          Punctuation
  Pc         Connector punctuation
  Pd         Dash punctuation
  Pe         Close punctuation
  Pf         Final punctuation
  Pi         Initial punctuation
  Po         Other punctuation
  Ps         Open punctuation

  S          Symbol
  Sc         Currency symbol
  Sk         Modifier symbol
  Sm         Mathematical symbol
  So         Other symbol

  Z          Separator
  Zl         Line separator
  Zp         Paragraph separator
  Zs         Space separator


PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P

  Xan        Alphanumeric: union of properties L and N
  Xps        POSIX space: property Z or tab, NL, VT, FF, CR
  Xsp        Perl space: property Z or tab, NL, FF, CR
  Xwd        Perl word: property Xan or underscore


SCRIPT NAMES FOR \p AND \P

Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi.


CHARACTER CLASSES

  [...]       positive character class
  [^...]      negative character class
  [x-y]       range (can be used for hex characters)
  [[:xxx:]]   positive POSIX named set
  [[:^xxx:]]  negative POSIX named set

  alnum       alphanumeric
  alpha       alphabetic
  ascii       0-127
  blank       space or tab
  cntrl       control character
  digit       decimal digit
  graph       printing, excluding space
  lower       lower case letter
  print       printing, including space
  punct       printing, excluding alphanumeric
  space       white space
  upper       upper case letter
  word        same as \w
  xdigit      hexadecimal digit
In PCRE, POSIX character set names recognize only ASCII characters by default, but some of them use Unicode properties if PCRE_UCP is set. You can use \Q...\E inside a character class.


QUANTIFIERS

  ?           0 or 1, greedy
  ?+          0 or 1, possessive
  ??          0 or 1, lazy
  *           0 or more, greedy
  *+          0 or more, possessive
  *?          0 or more, lazy
  +           1 or more, greedy
  ++          1 or more, possessive
  +?          1 or more, lazy
  {n}         exactly n
  {n,m}       at least n, no more than m, greedy
  {n,m}+      at least n, no more than m, possessive
  {n,m}?      at least n, no more than m, lazy
  {n,}        n or more, greedy
  {n,}+       n or more, possessive
  {n,}?       n or more, lazy


ANCHORS AND SIMPLE ASSERTIONS

  \b          word boundary
  \B          not a word boundary
  ^           start of subject
               also after internal newline in multiline mode
  \A          start of subject
  $           end of subject
               also before newline at end of subject
               also before internal newline in multiline mode
  \Z          end of subject
               also before newline at end of subject
  \z          end of subject
  \G          first matching position in subject


MATCH POINT RESET

  \K          reset start of match


ALTERNATION

  expr|expr|expr...


CAPTURING

  (...)           capturing group
  (?<name>...)    named capturing group (Perl)
  (?'name'...)    named capturing group (Perl)
  (?P<name>...)   named capturing group (Python)
  (?:...)         non-capturing group
  (?|...)         non-capturing group; reset group numbers for
                   capturing groups in each alternative


ATOMIC GROUPS

  (?>...)         atomic, non-capturing group


COMMENT

  (?#....)        comment (not nestable)


OPTION SETTING

  (?i)            caseless
  (?J)            allow duplicate names
  (?m)            multiline
  (?s)            single line (dotall)
  (?U)            default ungreedy (lazy)
  (?x)            extended (ignore white space)
  (?-...)         unset option(s)
The following are recognized only at the start of a pattern or after one of the newline-setting options with similar syntax:
  (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
  (*UTF8)         set UTF-8 mode: 8-bit library (PCRE_UTF8)
  (*UTF16)        set UTF-16 mode: 16-bit library (PCRE_UTF16)
  (*UCP)          set PCRE_UCP (use Unicode properties for \d etc)


LOOKAHEAD AND LOOKBEHIND ASSERTIONS

  (?=...)         positive look ahead
  (?!...)         negative look ahead
  (?<=...)        positive look behind
  (?<!...)        negative look behind
Each top-level branch of a look behind must be of a fixed length.


BACKREFERENCES

  \n              reference by number (can be ambiguous)
  \gn             reference by number
  \g{n}           reference by number
  \g{-n}          relative reference by number
  \k<name>        reference by name (Perl)
  \k'name'        reference by name (Perl)
  \g{name}        reference by name (Perl)
  \k{name}        reference by name (.NET)
  (?P=name)       reference by name (Python)


SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)

  (?R)            recurse whole pattern
  (?n)            call subpattern by absolute number
  (?+n)           call subpattern by relative number
  (?-n)           call subpattern by relative number
  (?&name)        call subpattern by name (Perl)
  (?P>name)       call subpattern by name (Python)
  \g<name>        call subpattern by name (Oniguruma)
  \g'name'        call subpattern by name (Oniguruma)
  \g<n>           call subpattern by absolute number (Oniguruma)
  \g'n'           call subpattern by absolute number (Oniguruma)
  \g<+n>          call subpattern by relative number (PCRE extension)
  \g'+n'          call subpattern by relative number (PCRE extension)
  \g<-n>          call subpattern by relative number (PCRE extension)
  \g'-n'          call subpattern by relative number (PCRE extension)


CONDITIONAL PATTERNS

  (?(condition)yes-pattern)
  (?(condition)yes-pattern|no-pattern)

  (?(n)...        absolute reference condition
  (?(+n)...       relative reference condition
  (?(-n)...       relative reference condition
  (?(<name>)...   named reference condition (Perl)
  (?('name')...   named reference condition (Perl)
  (?(name)...     named reference condition (PCRE)
  (?(R)...        overall recursion condition
  (?(Rn)...       specific group recursion condition
  (?(R&name)...   specific recursion condition
  (?(DEFINE)...   define subpattern for reference
  (?(assert)...   assertion condition


BACKTRACKING CONTROL

The following act immediately they are reached:

  (*ACCEPT)       force successful match
  (*FAIL)         force backtrack; synonym (*F)
  (*MARK:NAME)    set name to be passed back; synonym (*:NAME)
The following act only when a subsequent match failure causes a backtrack to reach them. They all force a match failure, but they differ in what happens afterwards. Those that advance the start-of-match point do so only if the pattern is not anchored.
  (*COMMIT)       overall failure, no advance of starting point
  (*PRUNE)        advance to next starting character
  (*PRUNE:NAME)   equivalent to (*MARK:NAME)(*PRUNE)
  (*SKIP)         advance to current matching position
  (*SKIP:NAME)    advance to position corresponding to an earlier
                  (*MARK:NAME); if not found, the (*SKIP) is ignored
  (*THEN)         local failure, backtrack to next alternation
  (*THEN:NAME)    equivalent to (*MARK:NAME)(*THEN)


NEWLINE CONVENTIONS

These are recognized only at the very start of the pattern or after a (*BSR_...), (*UTF8), (*UTF16) or (*UCP) option.

  (*CR)           carriage return only
  (*LF)           linefeed only
  (*CRLF)         carriage return followed by linefeed
  (*ANYCRLF)      all three of the above
  (*ANY)          any Unicode newline sequence


WHAT \R MATCHES

These are recognized only at the very start of the pattern or after a (*...) option that sets the newline convention or a UTF or UCP mode.

  (*BSR_ANYCRLF)  CR, LF, or CRLF
  (*BSR_UNICODE)  any Unicode newline sequence


CALLOUTS

  (?C)      callout
  (?Cn)     callout with data n


SEE ALSO

pcrepattern(3), pcreapi(3), pcrecallout(3), pcrematching(3), pcre(3).


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 10 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_free_substring.html0000644000222100022210000000226311775533017015750 00000000000000 pcre_free_substring specification

pcre_free_substring man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

void pcre_free_substring(const char *stringptr);

void pcre16_free_substring(PCRE_SPTR16 stringptr);


DESCRIPTION

This is a convenience function for freeing the store obtained by a previous call to pcre[16]_get_substring() or pcre[16]_get_named_substring(). Its only argument is a pointer to the string.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrestack.html0000644000222100022210000002250411775533020013667 00000000000000 pcrestack specification

pcrestack man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

PCRE DISCUSSION OF STACK USAGE

When you call pcre[16]_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 proceeds deeper and deeper into the tree of possibilities, the recursion depth increases. The match() function is also called in other circumstances, for example, whenever a parenthesized sub-pattern is entered, and in certain cases of repetition.

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 above comments apply when pcre[16]_exec() is run in its normal interpretive manner. If the pattern was studied with the PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was successful, and the options passed to pcre[16]_exec() were not incompatible, the matching process uses the JIT-compiled code instead of the match() function. In this case, the memory requirements are handled entirely differently. See the pcrejit documentation for details.

The pcre[16]_dfa_exec() function operates in an entirely different way, and uses recursion only when there is a regular expression recursion or subroutine call in the pattern. This includes the processing of assertion and "once-only" subpatterns, which are handled like subroutine calls. Normally, these are never very deep, and the limit on the complexity of pcre[16]_dfa_exec() is controlled by the amount of workspace it is given. However, it is possible to write patterns with runaway infinite recursions; such patterns will cause pcre[16]_dfa_exec() to run out of stack. At present, there is no protection against this.

The comments that follow do NOT apply to pcre[16]_dfa_exec(); they are relevant only for pcre[16]_exec() without the JIT optimization.


Reducing pcre[16]_exec()'s stack usage

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 therefore 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 character. 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. Recursion 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.

This example shows that one way of avoiding stack problems when matching long subject strings is to write repeated parenthesized subpatterns to match more than one character whenever possible.


Compiling PCRE to use heap instead of stack for pcre[16]_exec()

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 when pcre[16]_exec() is running. This makes it run a lot more slowly, however. Details of how to do this are given in the pcrebuild documentation. When built in this way, instead of using the stack, PCRE obtains and frees memory by calling the functions that are pointed to by the pcre[16]_stack_malloc and pcre[16]_stack_free variables. By default, these point to malloc() and free(), but you can replace the pointers to cause PCRE to use your own functions. Since the block sizes are always the same, and are always freed in reverse order, it may be possible to implement customized memory handlers that are more efficient than the standard functions.


Limiting pcre[16]_exec()'s stack usage

You can set limits on the number of times that match() is called, both in total and recursively. If a limit is exceeded, pcre[16]_exec() returns an error code. Setting suitable limits should prevent it from running out of stack. The default values of the limits are very large, and unlikely ever to operate. They can be changed when PCRE is built, and they can also be set when pcre[16]_exec() is called. For details of these interfaces, see the pcrebuild documentation and the section on extra data for pcre[16]_exec() in the 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.

In Unix-like environments, the pcretest test program has a command line option (-S) that can be used to increase the size of its stack. As long as the stack is large enough, another option (-M) can be used to find the smallest limits that allow a particular pattern to match a given subject string. This is done by calling pcre[16]_exec() repeatedly with different limits.


Obtaining an estimate of stack usage

The actual amount of stack used per recursion can vary quite a lot, depending on the compiler that was used to build PCRE and the optimization or debugging options that were set for it. The rule of thumb value of 500 bytes mentioned above may be larger or smaller than what is actually needed. A better approximation can be obtained by running this command:

  pcretest -m -C
The -C option causes pcretest to output information about the options with which PCRE was compiled. When -m is also given (before -C), information about stack use is given in a line like this:
  Match recursion uses stack: approximate frame size = 640 bytes
The value is approximate because some recursions need a bit more (up to perhaps 16 more bytes).

If the above command is given when PCRE is compiled to use the heap instead of the stack for recursion, the value that is output is the size of each block that is obtained from the heap.


Changing stack size in Unix-like systems

In Unix-like environments, there is not often a problem with the stack unless very long strings are involved, 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
Unfortunately, the effect of running out of stack is often SIGSEGV, though sometimes a more explicit 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[16]_exec().


Changing stack size in Mac OS X

Using setrlimit(), as described above, should also work on Mac OS X. It is also possible to set a stack size when linking a program. There is a discussion about stack sizes in Mac OS X at this web site: http://developer.apple.com/qa/qa2005/qa1419.html.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 21 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_fullinfo.html0000644000222100022210000000700011775533017014537 00000000000000 pcre_fullinfo specification

pcre_fullinfo man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where);

int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, int what, void *where);


DESCRIPTION

This function returns information about a compiled pattern. Its arguments are:

  code                      Compiled regular expression
  extra                     Result of pcre[16]_study() or NULL
  what                      What information is required
  where                     Where to put the information
The following information is available:
  PCRE_INFO_BACKREFMAX      Number of highest back reference
  PCRE_INFO_CAPTURECOUNT    Number of capturing subpatterns
  PCRE_INFO_DEFAULT_TABLES  Pointer to default tables
  PCRE_INFO_FIRSTBYTE       Fixed first data unit for a match, or
                              -1 for start of string
                                 or after newline, or
                              -2 otherwise
  PCRE_INFO_FIRSTTABLE      Table of first data units (after studying)
  PCRE_INFO_HASCRORLF       Return 1 if explicit CR or LF matches exist
  PCRE_INFO_JCHANGED        Return 1 if (?J) or (?-J) was used
  PCRE_INFO_JIT             Return 1 after successful JIT compilation
  PCRE_INFO_JITSIZE         Size of JIT compiled code
  PCRE_INFO_LASTLITERAL     Literal last data unit required
  PCRE_INFO_MINLENGTH       Lower bound length of matching strings
  PCRE_INFO_NAMECOUNT       Number of named subpatterns
  PCRE_INFO_NAMEENTRYSIZE   Size of name table entry
  PCRE_INFO_NAMETABLE       Pointer to name table
  PCRE_INFO_OKPARTIAL       Return 1 if partial matching can be tried
                              (always returns 1 after release 8.00)
  PCRE_INFO_OPTIONS         Option bits used for compilation
  PCRE_INFO_SIZE            Size of compiled pattern
  PCRE_INFO_STUDYSIZE       Size of study data
The where argument must point to an integer variable, except for the following what values:
  PCRE_INFO_DEFAULT_TABLES  const unsigned char *
  PCRE_INFO_FIRSTTABLE      const unsigned char *
  PCRE_INFO_NAMETABLE       PCRE_SPTR16           (16-bit library)
  PCRE_INFO_NAMETABLE       const unsigned char * (8-bit library)
  PCRE_INFO_OPTIONS         unsigned long int
  PCRE_INFO_SIZE            size_t
The yield of the function is zero on success or:
  PCRE_ERROR_NULL           the argument code was NULL
                            the argument where was NULL
  PCRE_ERROR_BADMAGIC       the "magic number" was not found
  PCRE_ERROR_BADOPTION      the value of what was invalid

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrecallout.html0000644000222100022210000002304311775533017014232 00000000000000 pcrecallout specification

pcrecallout man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


PCRE CALLOUTS

int (*pcre_callout)(pcre_callout_block *);

int (*pcre16_callout)(pcre16_callout_block *);

PCRE provides a feature called "callout", which is a means of temporarily passing control to the caller of PCRE in the middle of pattern matching. The caller of PCRE provides an external function by putting its entry point in the global variable pcre_callout (pcre16_callout for the 16-bit library). 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. Different callout points can be identified by putting 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 option bit is set when a pattern is compiled, PCRE automatically inserts callouts, all with number 255, before each item in the pattern. For example, if PCRE_AUTO_CALLOUT is used with the pattern
  A(\d{2}|--)
it is processed as if it were

(?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)

Notice that there is a callout before and after each parenthesis and alternation bar. Automatic callouts can be used for tracking the progress of pattern matching. The pcretest command has an option that sets automatic callouts; when it is used, the output indicates how the pattern is matched. This is useful information when you are trying to optimize the performance of a particular pattern.

The use of callouts in a pattern makes it ineligible for optimization by the just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE option always fails.


MISSING CALLOUTS

You should be aware that, because of optimizations in the way PCRE matches patterns by default, callouts sometimes do not happen. For example, if the pattern is

  ab(?C4)cd
PCRE knows that any matching string must contain the letter "d". If the subject string is "abyz", the lack of "d" means that matching doesn't ever start, and the callout is never reached. However, with "abyd", though the result is still no match, the callout is obeyed.

If the pattern is studied, PCRE knows the minimum length of a matching string, and will immediately give a "no match" return without actually running a match if the subject is not long enough, or, for unanchored patterns, if it has been scanned far enough.

You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE option to the matching function, or by starting the pattern with (*NO_START_OPT). This slows down the matching process, but does ensure that callouts such as the example above are obeyed.


THE CALLOUT INTERFACE

During matching, when PCRE reaches a callout point, the external function defined by pcre_callout or pcre16_callout is called (if it is set). This applies to both normal and DFA matching. The only argument to the callout function is a pointer to a pcre_callout or pcre16_callout block. These structures contains the following fields:

  int           version;
  int           callout_number;
  int          *offset_vector;
  const char   *subject;           (8-bit version)
  PCRE_SPTR16   subject;           (16-bit version)
  int           subject_length;
  int           start_match;
  int           current_position;
  int           capture_top;
  int           capture_last;
  void         *callout_data;
  int           pattern_position;
  int           next_item_length;
  const unsigned char *mark;       (8-bit version)
  const PCRE_UCHAR16  *mark;       (16-bit version)
The version field is an integer containing the version number of the block format. The initial version was 0; the current version is 2. The version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields.

The callout_number field contains the number of the callout, as compiled into the pattern (that is, the number after ?C for manual callouts, and 255 for automatically generated callouts).

The offset_vector field is a pointer to the vector of offsets that was passed by the caller to the matching function. When pcre_exec() or pcre16_exec() is used, the contents can be inspected, in order to extract substrings that have been matched so far, in the same way as for extracting substrings after a match has completed. For the DFA matching functions, this field is not useful.

The subject and subject_length fields contain copies of the values that were passed to the matching function.

The start_match field normally contains the offset within the subject at which the current match attempt started. However, if the escape sequence \K has been encountered, this value is changed to reflect the modified starting point. If the pattern is not anchored, the callout function may be called several times from the same point in the pattern for different starting points in the subject.

The current_position field contains the offset within the subject of the current match pointer.

When the pcre_exec() or pcre16_exec() is used, the capture_top field contains one more than the number of the highest numbered captured substring so far. If no substrings have been captured, the value of capture_top is one. This is always the case when the DFA functions are used, because they do not support captured substrings.

The capture_last field contains the number of the most recently captured substring. If no substrings have been captured, its value is -1. This is always the case for the DFA matching functions.

The callout_data field contains a value that is passed to a matching function specifically so that it can be passed back in callouts. It is passed in the callout_data field of a pcre_extra or pcre16_extra data structure. If no such data was passed, the value of callout_data in a callout block is NULL. There is a description of the pcre_extra structure in the pcreapi documentation.

The pattern_position field is present from version 1 of the callout structure. It contains the offset to the next item to be matched in the pattern string.

The next_item_length field is present from version 1 of the callout structure. It contains the length of the next item to be matched in the pattern string. When the callout immediately precedes an alternation bar, a closing parenthesis, or the end of the pattern, the length is zero. When the callout precedes an opening parenthesis, the length is that of the entire subpattern.

The pattern_position and next_item_length fields are intended to help in distinguishing between different automatic callouts, which all have the same callout number. However, they are set for all callouts.

The mark field is present from version 2 of the callout structure. In callouts from pcre_exec() or pcre16_exec() it contains a pointer to the zero-terminated name of the most recently passed (*MARK), (*PRUNE), or (*THEN) item in the match, or NULL if no such items have been passed. Instances of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In callouts from the DFA matching functions this field always contains NULL.


RETURN VALUES

The external callout function returns an integer to PCRE. If the value is zero, matching proceeds as normal. If the value is greater than zero, matching fails at the current point, but the testing of other matching possibilities goes ahead, just as if a lookahead assertion had failed. If the value is less than zero, the match is abandoned, the matching function returns the negative value.

Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a standard "no match" failure. The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions; it will never be used by PCRE itself.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 08 Janurary 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcretest.html0000644000222100022210000012414511775533017013553 00000000000000 pcretest specification

pcretest man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


SYNOPSIS

pcretest [options] [input file [output file]]

pcretest was written as a test program for the PCRE regular expression library itself, but it can also be used for experimenting with regular expressions. This document describes the features of the test program; for details of the regular expressions themselves, see the pcrepattern documentation. For details of the PCRE library function calls and their options, see the pcreapi and pcre16 documentation. The input for pcretest is a sequence of regular expression patterns and strings to be matched, as described below. The output shows the result of each match. Options on the command line and the patterns control PCRE options and exactly what is output.


PCRE's 8-BIT and 16-BIT LIBRARIES

From release 8.30, two separate PCRE libraries can be built. The original one supports 8-bit character strings, whereas the newer 16-bit library supports character strings encoded in 16-bit units. The pcretest program can be used to test both libraries. However, it is itself still an 8-bit program, reading 8-bit input and writing 8-bit output. When testing the 16-bit library, the patterns and data strings are converted to 16-bit format before being passed to the PCRE library functions. Results are converted to 8-bit for output.

References to functions and structures of the form pcre[16]_xx below mean "pcre_xx when using the 8-bit library or pcre16_xx when using the 16-bit library".


COMMAND LINE OPTIONS

-16 If both the 8-bit and the 16-bit libraries have been built, this option causes the 16-bit library to be used. If only the 16-bit library has been built, this is the default (so has no effect). If only the 8-bit library has been built, this option causes an error.

-b Behave as if each pattern has the /B (show byte code) modifier; the internal form is output after compilation.

-C Output the version number of the PCRE library, and all available information about the optional features that are included, and then exit. All other options are ignored.

-C option Output information about a specific build-time option, then exit. This functionality is intended for use in scripts such as RunTest. The following options output the value indicated:

  linksize   the internal link size (2, 3, or 4)
  newline    the default newline setting:
               CR, LF, CRLF, ANYCRLF, or ANY
The following options output 1 for true or zero for false:
  jit        just-in-time support is available
  pcre16     the 16-bit library was built
  pcre8      the 8-bit library was built
  ucp        Unicode property support is available
  utf        UTF-8 and/or UTF-16 support is available

-d Behave as if each pattern has the /D (debug) modifier; the internal form and information about the compiled pattern is output after compilation; -d is equivalent to -b -i.

-dfa Behave as if each data line contains the \D escape sequence; this causes the alternative matching function, pcre[16]_dfa_exec(), to be used instead of the standard pcre[16]_exec() function (more detail is given below).

-help Output a brief summary these options and then exit.

-i Behave as if each pattern has the /I modifier; information about the compiled pattern is given after compilation.

-M Behave as if each data line contains the \M escape sequence; this causes PCRE to discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings by calling pcre[16]_exec() repeatedly with different limits.

-m Output the size of each compiled pattern after it has been compiled. This is equivalent to adding /M to each regular expression. The size is given in bytes for both libraries.

-o osize Set the number of elements in the output vector that is used when calling pcre[16]_exec() or pcre[16]_dfa_exec() to be osize. The default value is 45, which is enough for 14 capturing subexpressions for pcre[16]_exec() or 22 different matches for pcre[16]_dfa_exec(). The vector size can be changed for individual matching calls by including \O in the data line (see below).

-p Behave as if each pattern has the /P modifier; the POSIX wrapper API is used to call PCRE. None of the other options has any effect when -p is set. This option can be used only with the 8-bit library.

-q Do not output the version number of pcretest at the start of execution.

-S size On Unix-like systems, set the size of the run-time stack to size megabytes.

-s or -s+ Behave as if each pattern has the /S modifier; in other words, force each pattern to be studied. If -s+ is used, all the JIT compile options are passed to pcre[16]_study(), causing just-in-time optimization to be set up if it is available, for both full and partial matching. Specific JIT compile options can be selected by following -s+ with a digit in the range 1 to 7, which selects the JIT compile modes as follows:

  1  normal match only
  2  soft partial match only
  3  normal match and soft partial match
  4  hard partial match only
  6  soft and hard partial match
  7  all three modes (default)
If -s++ is used instead of -s+ (with or without a following digit), the text "(JIT)" is added to the first output line after a match or no match when JIT-compiled code was actually used.

If the /I or /D option is present on a pattern (requesting output about the compiled pattern), information about the result of studying is not included when studying is caused only by -s and neither -i nor -d is present on the command line. This behaviour means that the output from tests that are run with and without -s should be identical, except when options that output information about the actual running of a match are set.

The -M, -t, and -tm options, which give information about resources used, are likely to produce different output with and without -s. Output may also differ if the /C option is present on an individual pattern. This uses callouts to trace the the matching process, and this may be different between studied and non-studied patterns. If the pattern contains (*MARK) items there may also be differences, for the same reason. The -s command line option can be overridden for specific patterns that should never be studied (see the /S pattern modifier below).

-t Run each compile, study, and match many times with a timer, and output resulting time per compile or match (in milliseconds). Do not set -m with -t, because you will then get the size output a zillion times, and the timing will be distorted. You can control the number of iterations that are used for timing by following -t with a number (as a separate item on the command line). For example, "-t 1000" would iterate 1000 times. The default is to iterate 500000 times.

-tm This is like -t except that it times only the matching phase, not the compile or study phases.


DESCRIPTION

If pcretest is given two filename arguments, it reads from the first and writes to the second. If it is given only one filename argument, it reads from that file and writes to stdout. Otherwise, it reads from stdin and writes to stdout, and prompts for each line of input, using "re>" to prompt for regular expressions, and "data>" to prompt for data lines.

When pcretest is built, a configuration option can specify that it should be linked with the libreadline library. When this is done, if the input is from a terminal, it is read using the readline() function. This provides line-editing and history facilities. The output from the -help option states whether or not readline() will be used.

The program handles any number of sets of input on a single input file. Each set starts with a regular expression, and continues with any number of data lines to be matched against the pattern.

Each data line is matched separately and independently. If you want to do multi-line matches, you have to use the \n escape sequence (or \r or \r\n, etc., depending on the newline setting) in a single line of input to encode the newline sequences. There is no limit on the length of data lines; the input buffer is automatically extended if it is too small.

An empty line signals the end of the data lines, at which point a new regular expression is read. The regular expressions are given enclosed in any non-alphanumeric delimiters other than backslash, for example:

  /(a|bc)x+yz/
White space before the initial delimiter is ignored. A regular expression may be continued over several input lines, in which case the newline characters are included within it. It is possible to include the delimiter within the pattern by escaping it, for example
  /abc\/def/
If you do so, the escape and the delimiter form part of the pattern, but since delimiters are always non-alphanumeric, this does not affect its interpretation. If the terminating delimiter is immediately followed by a backslash, for example,
  /abc/\
then a backslash is added to the end of the pattern. This is done to provide a way of testing the error condition that arises if a pattern finishes with a backslash, because
  /abc\/
is interpreted as the first line of a pattern that starts with "abc/", causing pcretest to read the next line as a continuation of the regular expression.


PATTERN MODIFIERS

A pattern may be followed by any number of modifiers, which are mostly single characters. Following Perl usage, these are referred to below as, for example, "the /i modifier", even though the delimiter of the pattern need not always be a slash, and no slash is used when writing modifiers. White space may appear between the final pattern delimiter and the first modifier, and between the modifiers themselves.

The /i, /m, /s, and /x modifiers set the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when pcre[16]_compile() is called. These four modifier letters have the same effect as they do in Perl. For example:

  /caseless/i
The following table shows additional modifiers for setting PCRE compile-time options that do not correspond to anything in Perl:
  /8              PCRE_UTF8           ) when using the 8-bit
  /?              PCRE_NO_UTF8_CHECK  )   library

  /8              PCRE_UTF16          ) when using the 16-bit
  /?              PCRE_NO_UTF16_CHECK )   library

  /A              PCRE_ANCHORED
  /C              PCRE_AUTO_CALLOUT
  /E              PCRE_DOLLAR_ENDONLY
  /f              PCRE_FIRSTLINE
  /J              PCRE_DUPNAMES
  /N              PCRE_NO_AUTO_CAPTURE
  /U              PCRE_UNGREEDY
  /W              PCRE_UCP
  /X              PCRE_EXTRA
  /Y              PCRE_NO_START_OPTIMIZE
  /<JS>           PCRE_JAVASCRIPT_COMPAT
  /<cr>           PCRE_NEWLINE_CR
  /<lf>           PCRE_NEWLINE_LF
  /<crlf>         PCRE_NEWLINE_CRLF
  /<anycrlf>      PCRE_NEWLINE_ANYCRLF
  /<any>          PCRE_NEWLINE_ANY
  /<bsr_anycrlf>  PCRE_BSR_ANYCRLF
  /<bsr_unicode>  PCRE_BSR_UNICODE
The modifiers that are enclosed in angle brackets are literal strings as shown, including the angle brackets, but the letters within can be in either case. This example sets multiline matching with CRLF as the line ending sequence:
  /^abc/m<CRLF>
As well as turning on the PCRE_UTF8/16 option, the /8 modifier causes all non-printing characters in output strings to be printed using the \x{hh...} notation. Otherwise, those less than 0x100 are output in hex without the curly brackets.

Full details of the PCRE options are given in the pcreapi documentation.


Finding all matches in a string

Searching for all possible matches within each subject string can be requested by the /g or /G modifier. After finding a match, PCRE is called again to search the remainder of the subject string. The difference between /g and /G is that the former uses the startoffset argument to pcre[16]_exec() to start searching at a new point within the entire string (which is in effect what Perl does), whereas the latter passes over a shortened substring. This makes a difference to the matching process if the pattern begins with a lookbehind assertion (including \b or \B).

If any call to pcre[16]_exec() in a /g or /G sequence matches an empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART 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, and the normal match is retried. This imitates the way Perl handles such cases when using the /g modifier or the split() function. Normally, the start offset is advanced by one character, but if the newline convention recognizes CRLF as a newline, and the current character is CR followed by LF, an advance of two is used.


Other modifiers

There are yet more modifiers for controlling the way pcretest operates.

The /+ modifier requests that as well as outputting the substring that matched the entire pattern, pcretest should in addition output the remainder of the subject string. This is useful for tests where the subject contains multiple copies of the same substring. If the + modifier appears twice, the same action is taken for captured substrings. In each case the remainder is output on the following line with a plus character following the capture number. Note that this modifier must not immediately follow the /S modifier because /S+ and /S++ have other meanings.

The /= modifier requests that the values of all potential captured parentheses be output after a match. By default, only those up to the highest one actually used in the match are output (corresponding to the return code from pcre[16]_exec()). Values in the offsets vector corresponding to higher numbers should be set to -1, and these are output as "<unset>". This modifier gives a way of checking that this is happening.

The /B modifier is a debugging feature. It requests that pcretest output a representation of the compiled code after compilation. Normally this information contains length and offset values; however, if /Z is also present, this data is replaced by spaces. This is a special feature for use in the automatic test scripts; it ensures that the same output is generated for different internal link sizes.

The /D modifier is a PCRE debugging feature, and is equivalent to /BI, that is, both the /B and the /I modifiers.

The /F modifier causes pcretest to flip the byte order of the 2-byte and 4-byte fields in the compiled pattern. This facility is for testing the feature in PCRE that allows it to execute patterns that were compiled on a host with a different endianness. This feature is not available when the POSIX interface to PCRE is being used, that is, when the /P pattern modifier is specified. See also the section about saving and reloading compiled patterns below.

The /I modifier requests that pcretest output information about the compiled pattern (whether it is anchored, has a fixed first character, and so on). It does this by calling pcre[16]_fullinfo() after compiling a pattern. If the pattern is studied, the results of that are also output.

The /K modifier requests pcretest to show names from backtracking control verbs that are returned from calls to pcre[16]_exec(). It causes pcretest to create a pcre[16]_extra block if one has not already been created by a call to pcre[16]_study(), and to set the PCRE_EXTRA_MARK flag and the mark field within it, every time that pcre[16]_exec() is called. If the variable that the mark field points to is non-NULL for a match, non-match, or partial match, pcretest prints the string to which it points. For a match, this is shown on a line by itself, tagged with "MK:". For a non-match it is added to the message.

The /L modifier must be followed directly by the name of a locale, for example,

  /pattern/Lfr_FR
For this reason, it must be the last modifier. The given locale is set, pcre[16]_maketables() is called to build a set of character tables for the locale, and this is then passed to pcre[16]_compile() when compiling the regular expression. Without an /L (or /T) modifier, NULL is passed as the tables pointer; that is, /L applies only to the expression on which it appears.

The /M modifier causes the size in bytes of the memory block used to hold the compiled pattern to be output. This does not include the size of the pcre[16] block; it is just the actual compiled data. If the pattern is successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the JIT compiled code is also output.

If the /S modifier appears once, it causes pcre[16]_study() to be called after the expression has been compiled, and the results used when the expression is matched. If /S appears twice, it suppresses studying, even if it was requested externally by the -s command line option. This makes it possible to specify that certain patterns are always studied, and others are never studied, independently of -s. This feature is used in the test files in a few cases where the output is different when the pattern is studied.

If the /S modifier is immediately followed by a + character, the call to pcre[16]_study() is made with all the JIT study options, requesting just-in-time optimization support if it is available, for both normal and partial matching. If you want to restrict the JIT compiling modes, you can follow /S+ with a digit in the range 1 to 7:

  1  normal match only
  2  soft partial match only
  3  normal match and soft partial match
  4  hard partial match only
  6  soft and hard partial match
  7  all three modes (default)
If /S++ is used instead of /S+ (with or without a following digit), the text "(JIT)" is added to the first output line after a match or no match when JIT-compiled code was actually used.

Note that there is also an independent /+ modifier; it must not be given immediately after /S or /S+ because this will be misinterpreted.

If JIT studying is successful, the compiled JIT code will automatically be used when pcre[16]_exec() is run, except when incompatible run-time options are specified. For more details, see the pcrejit documentation. See also the \J escape sequence below for a way of setting the size of the JIT stack.

The /T modifier must be followed by a single digit. It causes a specific set of built-in character tables to be passed to pcre[16]_compile(). It is used in the standard PCRE tests to check behaviour with different character tables. The digit specifies the tables as follows:

  0   the default ASCII tables, as distributed in
        pcre_chartables.c.dist
  1   a set of tables defining ISO 8859 characters
In table 1, some characters whose codes are greater than 128 are identified as letters, digits, spaces, etc.


Using the POSIX wrapper API

The /P modifier causes pcretest to call PCRE via the POSIX wrapper API rather than its native API. This supports only the 8-bit library. When /P is set, the following modifiers set options for the regcomp() function:

  /i    REG_ICASE
  /m    REG_NEWLINE
  /N    REG_NOSUB
  /s    REG_DOTALL     )
  /U    REG_UNGREEDY   ) These options are not part of
  /W    REG_UCP        )   the POSIX standard
  /8    REG_UTF8       )
The /+ modifier works as described above. All other modifiers are ignored.


DATA LINES

Before each data line is passed to pcre[16]_exec(), leading and trailing white space is removed, and it is then scanned for \ escapes. Some of these are pretty esoteric features, intended for checking out some of the more complicated features of PCRE. If you are just testing "ordinary" regular expressions, you probably don't need any of these. The following escapes are recognized:

  \a         alarm (BEL, \x07)
  \b         backspace (\x08)
  \e         escape (\x27)
  \f         form feed (\x0c)
  \n         newline (\x0a)
  \qdd       set the PCRE_MATCH_LIMIT limit to dd (any number of digits)
  \r         carriage return (\x0d)
  \t         tab (\x09)
  \v         vertical tab (\x0b)
  \nnn       octal character (up to 3 octal digits); always
               a byte unless > 255 in UTF-8 or 16-bit mode
  \xhh       hexadecimal byte (up to 2 hex digits)
  \x{hh...}  hexadecimal character (any number of hex digits)
  \A         pass the PCRE_ANCHORED option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \B         pass the PCRE_NOTBOL option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \Cdd       call pcre[16]_copy_substring() for substring dd after a successful match (number less than 32)
  \Cname     call pcre[16]_copy_named_substring() for substring "name" after a successful match (name termin-
               ated by next non alphanumeric character)
  \C+        show the current captured substrings at callout time
  \C-        do not supply a callout function
  \C!n       return 1 instead of 0 when callout number n is reached
  \C!n!m     return 1 instead of 0 when callout number n is reached for the nth time
  \C*n       pass the number n (may be negative) as callout data; this is used as the callout return value
  \D         use the pcre[16]_dfa_exec() match function
  \F         only shortest match for pcre[16]_dfa_exec()
  \Gdd       call pcre[16]_get_substring() for substring dd after a successful match (number less than 32)
  \Gname     call pcre[16]_get_named_substring() for substring "name" after a successful match (name termin-
               ated by next non-alphanumeric character)
  \Jdd       set up a JIT stack of dd kilobytes maximum (any number of digits)
  \L         call pcre[16]_get_substringlist() after a successful match
  \M         discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings
  \N         pass the PCRE_NOTEMPTY option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the
               PCRE_NOTEMPTY_ATSTART option
  \Odd       set the size of the output vector passed to pcre[16]_exec() to dd (any number of digits)
  \P         pass the PCRE_PARTIAL_SOFT option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the
               PCRE_PARTIAL_HARD option
  \Qdd       set the PCRE_MATCH_LIMIT_RECURSION limit to dd (any number of digits)
  \R         pass the PCRE_DFA_RESTART option to pcre[16]_dfa_exec()
  \S         output details of memory get/free calls during matching
  \Y         pass the PCRE_NO_START_OPTIMIZE option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \Z         pass the PCRE_NOTEOL option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \?         pass the PCRE_NO_UTF[8|16]_CHECK option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \>dd       start the match at offset dd (optional "-"; then any number of digits); this sets the startoffset
               argument for pcre[16]_exec() or pcre[16]_dfa_exec()
  \<cr>      pass the PCRE_NEWLINE_CR option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \<lf>      pass the PCRE_NEWLINE_LF option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \<crlf>    pass the PCRE_NEWLINE_CRLF option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \<anycrlf> pass the PCRE_NEWLINE_ANYCRLF option to pcre[16]_exec() or pcre[16]_dfa_exec()
  \<any>     pass the PCRE_NEWLINE_ANY option to pcre[16]_exec() or pcre[16]_dfa_exec()
The use of \x{hh...} is not dependent on the use of the /8 modifier on the pattern. It is recognized always. There may be any number of hexadecimal digits inside the braces; invalid values provoke error messages.

Note that \xhh specifies one byte rather than one character in UTF-8 mode; this makes it possible to construct invalid UTF-8 sequences for testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8 character in UTF-8 mode, generating more than one byte if the value is greater than 127. When testing the 8-bit library not in UTF-8 mode, \x{hh} generates one byte for values less than 256, and causes an error for greater values.

In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it possible to construct invalid UTF-16 sequences for testing purposes.

The escapes that specify line ending sequences are literal strings, exactly as shown. No more than one newline setting should be present in any data line.

A backslash followed by anything else just escapes the anything else. If the very last character is a backslash, it is ignored. This gives a way of passing an empty line as data, since a real empty line terminates the data input.

The \J escape provides a way of setting the maximum stack size that is used by the just-in-time optimization code. It is ignored if JIT optimization is not being used. Providing a stack that is larger than the default 32K is necessary only for very complicated patterns.

If \M is present, pcretest calls pcre[16]_exec() several times, with different values in the match_limit and match_limit_recursion fields of the pcre[16]_extra data structure, until it finds the minimum numbers for each parameter that allow pcre[16]_exec() to complete without error. Because this is testing a specific feature of the normal interpretive pcre[16]_exec() execution, the use of any JIT optimization that might have been set up by the /S+ qualifier of -s+ option is disabled.

The match_limit number is a measure of the amount of backtracking that takes place, and checking it out can be instructive. For most simple matches, the number is quite small, but for patterns with very large numbers of matching possibilities, it can become large very quickly with increasing length of subject string. The match_limit_recursion number is a measure of how much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is needed to complete the match attempt.

When \O is used, the value specified may be higher or lower than the size set by the -O command line option (or defaulted to 45); \O applies only to the call of pcre[16]_exec() for the line in which it appears.

If the /P modifier was present on the pattern, causing the POSIX wrapper API to be used, the only option-setting sequences that have any effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to regexec().


THE ALTERNATIVE MATCHING FUNCTION

By default, pcretest uses the standard PCRE matching function, pcre[16]_exec() to match each data line. PCRE also supports an alternative matching function, pcre[16]_dfa_test(), which operates in a different way, and has some restrictions. The differences between the two functions are described in the pcrematching documentation.

If a data line contains the \D escape sequence, or if the command line contains the -dfa option, the alternative matching function is used. This function finds all possible matches at a given point. If, however, the \F escape sequence is present in the data line, it stops after the first match is found. This is always the shortest possible match.


DEFAULT OUTPUT FROM PCRETEST

This section describes the output when the normal matching function, pcre[16]_exec(), is being used.

When a match succeeds, pcretest outputs the list of captured substrings that pcre[16]_exec() returns, starting with number 0 for the string that matched the whole pattern. Otherwise, it outputs "No match" when the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the partially matching substring when pcre[16]_exec() returns PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was inspected during the partial match; it may include characters before the actual match start if a lookbehind assertion, \K, \b, or \B was involved.) For any other return, pcretest outputs the PCRE negative error number and a short descriptive phrase. If the error is a failed UTF string check, the offset of the start of the failing character and the reason code are also output, provided that the size of the output vector is at least two. Here is an example of an interactive pcretest run.

  $ pcretest
  PCRE version 8.13 2011-04-30

    re> /^abc(\d+)/
  data> abc123
   0: abc123
   1: 123
  data> xyz
  No match
Unset capturing substrings that are not followed by one that is set are not returned by pcre[16]_exec(), and are not shown by pcretest. In the following example, there are two capturing substrings, but when the first data line is matched, the second, unset substring is not shown. An "internal" unset substring is shown as "<unset>", as for the second data line.
    re> /(a)|(b)/
  data> a
   0: a
   1: a
  data> b
   0: b
   1: <unset>
   2: b
If the strings contain any non-printing characters, they are output as \xhh escapes if the value is less than 256 and UTF mode is not set. Otherwise they are output as \x{hh...} escapes. See below for the definition of non-printing characters. If the pattern has the /+ modifier, the output for substring 0 is followed by the the rest of the subject string, identified by "0+" like this:
    re> /cat/+
  data> cataract
   0: cat
   0+ aract
If the pattern has the /g or /G modifier, the results of successive matching attempts are output in sequence, like this:
    re> /\Bi(\w\w)/g
  data> Mississippi
   0: iss
   1: ss
   0: iss
   1: ss
   0: ipp
   1: pp
"No match" is output only if the first match attempt fails. Here is an example of a failure message (the offset 4 that is specified by \>4 is past the end of the subject string):
    re> /xyz/
  data> xyz\>4
  Error -24 (bad offset value)

If any of the sequences \C, \G, or \L are present in a data line that is successfully matched, the substrings extracted by the convenience functions are output with C, G, or L after the string number instead of a colon. This is in addition to the normal full list. The string length (that is, the return from the extraction function) is given in parentheses after each string for \C and \G.

Note that whereas patterns can be continued over several lines (a plain ">" prompt is used for continuations), data lines may not. However newlines can be included in data by means of the \n escape (or \r, \r\n, etc., depending on the newline sequence setting).


OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION

When the alternative matching function, pcre[16]_dfa_exec(), is used (by means of the \D escape sequence or the -dfa command line option), the output consists of a list of all the matches that start at the first point in the subject where there is at least one match. For example:

    re> /(tang|tangerine|tan)/
  data> yellow tangerine\D
   0: tangerine
   1: tang
   2: tan
(Using the normal matching function on this data finds only "tang".) The longest matching string is always given first (and numbered zero). After a PCRE_ERROR_PARTIAL return, the output is "Partial match:", followed by the partially matching substring. (Note that this is the entire substring that was inspected during the partial match; it may include characters before the actual match start if a lookbehind assertion, \K, \b, or \B was involved.)

If /g is present on the pattern, the search for further matches resumes at the end of the longest match. For example:

    re> /(tang|tangerine|tan)/g
  data> yellow tangerine and tangy sultana\D
   0: tangerine
   1: tang
   2: tan
   0: tang
   1: tan
   0: tan
Since the matching function does not support substring capture, the escape sequences that are concerned with captured substrings are not relevant.


RESTARTING AFTER A PARTIAL MATCH

When the alternative matching function has given the PCRE_ERROR_PARTIAL return, indicating that the subject partially matched the pattern, you can restart the match with additional subject data by means of the \R escape sequence. For example:

    re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
  data> 23ja\P\D
  Partial match: 23ja
  data> n05\R\D
   0: n05
For further information about partial matching, see the pcrepartial documentation.


CALLOUTS

If the pattern contains any callout requests, pcretest's callout function is called during matching. This works with both matching functions. By default, the called function displays the callout number, the start and current positions in the text at the callout time, and the next pattern item to be tested. For example:

  --->pqrabcdef
    0    ^  ^     \d
This output indicates that callout number 0 occurred for a match attempt starting at the fourth character of the subject string, when the pointer was at the seventh character of the data, and when the next pattern item was \d. Just one circumflex is output if the start and current positions are the same.

Callouts numbered 255 are assumed to be automatic callouts, inserted as a result of the /C pattern modifier. In this case, instead of showing the callout number, the offset in the pattern, preceded by a plus, is output. For example:

    re> /\d?[A-E]\*/C
  data> E*
  --->E*
   +0 ^      \d?
   +3 ^      [A-E]
   +8 ^^     \*
  +10 ^ ^
   0: E*
If a pattern contains (*MARK) items, an additional line is output whenever a change of latest mark is passed to the callout function. For example:
    re> /a(*MARK:X)bc/C
  data> abc
  --->abc
   +0 ^       a
   +1 ^^      (*MARK:X)
  +10 ^^      b
  Latest Mark: X
  +11 ^ ^     c
  +12 ^  ^
   0: abc
The mark changes between matching "a" and "b", but stays the same for the rest of the match, so nothing more is output. If, as a result of backtracking, the mark reverts to being unset, the text "<unset>" is output.

The callout function in pcretest returns zero (carry on matching) by default, but you can use a \C item in a data line (as described above) to change this and other parameters of the callout.

Inserting callouts can be helpful when using pcretest to check complicated regular expressions. For further information about callouts, see the pcrecallout documentation.


NON-PRINTING CHARACTERS

When pcretest is outputting text in the compiled version of a pattern, bytes other than 32-126 are always treated as non-printing characters are are therefore shown as hex escapes.

When pcretest is outputting text that is a matched part of a subject string, it behaves in the same way, unless a different locale has been set for the pattern (using the /L modifier). In this case, the isprint() function to distinguish printing and non-printing characters.


SAVING AND RELOADING COMPILED PATTERNS

The facilities described in this section are not available when the POSIX interface to PCRE is being used, that is, when the /P pattern modifier is specified.

When the POSIX interface is not in use, you can cause pcretest to write a compiled pattern to a file, by following the modifiers with > and a file name. For example:

  /pattern/im >/some/file
See the pcreprecompile documentation for a discussion about saving and re-using compiled patterns. Note that if the pattern was successfully studied with JIT optimization, the JIT data cannot be saved.

The data that is written is binary. The first eight bytes are the length of the compiled pattern data followed by the length of the optional study data, each written as four bytes in big-endian order (most significant byte first). If there is no study data (either the pattern was not studied, or studying did not return any data), the second length is zero. The lengths are followed by an exact copy of the compiled pattern. If there is additional study data, this (excluding any JIT data) follows immediately after the compiled pattern. After writing the file, pcretest expects to read a new pattern.

A saved pattern can be reloaded into pcretest by specifying < and a file name instead of a pattern. The name of the file must not contain a < character, as otherwise pcretest will interpret the line as a pattern delimited by < characters. For example:

   re> </some/file
  Compiled pattern loaded from /some/file
  No study data
If the pattern was previously studied with the JIT optimization, the JIT information cannot be saved and restored, and so is lost. When the pattern has been loaded, pcretest proceeds to read data lines in the usual way.

You can copy a file written by pcretest to a different host and reload it there, even if the new host has opposite endianness to the one on which the pattern was compiled. For example, you can compile on an i86 machine and run on a SPARC machine. When a pattern is reloaded on a host with different endianness, the confirmation message is changed to:

  Compiled pattern (byte-inverted) loaded from /some/file
The test suite contains some saved pre-compiled patterns with different endianness. These are reloaded using "<!" instead of just "<". This suppresses the "(byte-inverted)" text so that the output is the same on all hosts. It also forces debugging output once the pattern has been reloaded.

File names for saving and reloading can be absolute or relative, but note that the shell facility of expanding a file name that starts with a tilde (~) is not available.

The ability to save and reload files in pcretest is intended for testing and experimentation. It is not intended for production use because only a single pattern can be written to a file. Furthermore, there is no facility for supplying custom character tables for use with a reloaded pattern. If the original pattern was compiled with custom tables, an attempt to match a subject string using a reloaded pattern is likely to cause pcretest to crash. Finally, if you attempt to load a file that is not in the correct format, the result is undefined.


SEE ALSO

pcre(3), pcre16(3), pcreapi(3), pcrecallout(3), pcrejit, pcrematching(3), pcrepartial(d), pcrepattern(3), pcreprecompile(3).


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 21 February 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcreprecompile.html0000644000222100022210000001573311775533020014727 00000000000000 pcreprecompile specification

pcreprecompile man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


SAVING AND RE-USING PRECOMPILED PCRE PATTERNS

If you are running an application that uses a large number of regular expression patterns, it may be useful to store them in a precompiled form instead of having to compile them every time the application is run. If you are not using any private character tables (see the pcre_maketables() documentation), this is relatively straightforward. If you are using private tables, it is a little bit more complicated. However, if you are using the just-in-time optimization feature, it is not possible to save and reload the JIT data.

If you save compiled patterns to a file, you can copy them to a different host and run them there. If the two hosts have different endianness (byte order), you should run the pcre[16]_pattern_to_host_byte_order() function on the new host before trying to match the pattern. The matching functions return PCRE_ERROR_BADENDIANNESS if they detect a pattern with the wrong endianness.

Compiling regular expressions with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes, and saving and restoring a compiled pattern loses any JIT optimization data.


SAVING A COMPILED PATTERN

The value returned by pcre[16]_compile() points to a single block of memory that holds the compiled pattern and associated data. You can find the length of this block in bytes by calling pcre[16]_fullinfo() with an argument of PCRE_INFO_SIZE. You can then save the data in any appropriate manner. Here is sample code for the 8-bit library that compiles a pattern and writes it to a file. It assumes that the variable fd refers to a file that is open for output:

  int erroroffset, rc, size;
  char *error;
  pcre *re;

  re = pcre_compile("my pattern", 0, &error, &erroroffset, NULL);
  if (re == NULL) { ... handle errors ... }
  rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size);
  if (rc < 0) { ... handle errors ... }
  rc = fwrite(re, 1, size, fd);
  if (rc != size) { ... handle errors ... }
In this example, the bytes that comprise the compiled pattern are copied exactly. Note that this is binary data that may contain any of the 256 possible byte values. On systems that make a distinction between binary and non-binary data, be sure that the file is opened for binary output.

If you want to write more than one pattern to a file, you will have to devise a way of separating them. For binary data, preceding each pattern with its length is probably the most straightforward approach. Another possibility is to write out the data in hexadecimal instead of binary, one pattern to a line.

Saving compiled patterns in a file is only one possible way of storing them for later use. They could equally well be saved in a database, or in the memory of some daemon process that passes them via sockets to the processes that want them.

If the pattern has been studied, it is also possible to save the normal study data in a similar way to the compiled pattern itself. However, if the PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is created cannot be saved because it is too dependent on the current environment. When studying generates additional information, pcre[16]_study() returns a pointer to a pcre[16]_extra data block. Its format is defined in the section on matching a pattern in the pcreapi documentation. The study_data field points to the binary study data, and this is what you must save (not the pcre[16]_extra block itself). The length of the study data can be obtained by calling pcre[16]_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. Remember to check that pcre[16]_study() did return a non-NULL value before trying to save the study data.


RE-USING A PRECOMPILED PATTERN

Re-using a precompiled pattern is straightforward. Having reloaded it into main memory, called pcre[16]_pattern_to_host_byte_order() if necessary, you pass its pointer to pcre[16]_exec() or pcre[16]_dfa_exec() in the usual way.

However, if you passed a pointer to custom character tables when the pattern was compiled (the tableptr argument of pcre[16]_compile()), you must now pass a similar pointer to pcre[16]_exec() or pcre[16]_dfa_exec(), because the value saved with the compiled pattern will obviously be nonsense. A field in a pcre[16]_extra() block is used to pass this data, as described in the section on matching a pattern in the pcreapi documentation.

If you did not provide custom character tables when the pattern was compiled, the pointer in the compiled pattern is NULL, which causes the matching functions to use PCRE's internal tables. Thus, you do not need to take any special action at run time in this case.

If you saved study data with the compiled pattern, you need to create your own pcre[16]_extra data block and set the study_data field to point to the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA bit in the flags field to indicate that study data is present. Then pass the pcre[16]_extra block to the matching function in the usual way. If the pattern was studied for just-in-time optimization, that data cannot be saved, and so is lost by a save/restore cycle.


COMPATIBILITY WITH DIFFERENT PCRE RELEASES

In general, it is safest to recompile all saved patterns when you update to a new PCRE release, though not all updates actually require this.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 10 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrejit.html0000644000222100022210000004347111775533020013356 00000000000000 pcrejit specification

pcrejit man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


PCRE JUST-IN-TIME COMPILER SUPPORT

Just-in-time compiling is a heavyweight optimization that can greatly speed up pattern matching. However, it comes at the cost of extra processing before the match is performed. Therefore, it is of most benefit when the same pattern is going to be matched many times. This does not necessarily mean many calls of a matching function; if the pattern is not anchored, matching attempts may take place many times at various positions in the subject, even for a single call. Therefore, if the subject string is very long, it may still pay to use JIT for one-off matches.

JIT support applies only to the traditional Perl-compatible matching function. It does not apply when the DFA matching function is being used. The code for this support was written by Zoltan Herczeg.


8-BIT and 16-BIT SUPPORT

JIT support is available for both the 8-bit and 16-bit PCRE libraries. To keep this documentation simple, only the 8-bit interface is described in what follows. If you are using the 16-bit library, substitute the 16-bit functions and 16-bit structures (for example, pcre16_jit_stack instead of pcre_jit_stack).


AVAILABILITY OF JIT SUPPORT

JIT support is an optional feature of PCRE. The "configure" option --enable-jit (or equivalent CMake option) must be set when PCRE is built if you want to use JIT. The support is limited to the following hardware platforms:

  ARM v5, v7, and Thumb2
  Intel x86 32-bit and 64-bit
  MIPS 32-bit
  Power PC 32-bit and 64-bit
If --enable-jit is set on an unsupported platform, compilation fails.

A program that is linked with PCRE 8.20 or later can tell if JIT support is available by calling pcre_config() with the PCRE_CONFIG_JIT option. The result is 1 when JIT is available, and 0 otherwise. However, a simple program does not need to check this in order to use JIT. The API is implemented in a way that falls back to the interpretive code if JIT is not available.

If your program may sometimes be linked with versions of PCRE that are older than 8.20, but you want to use JIT when it is available, you can test the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT macro such as PCRE_CONFIG_JIT, for compile-time control of your code.


SIMPLE USE OF JIT

You have to do two things to make use of the JIT support in the simplest way:

  (1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for
      each compiled pattern, and pass the resulting pcre_extra block to
      pcre_exec().

  (2) Use pcre_free_study() to free the pcre_extra block when it is
      no longer needed, instead of just freeing it yourself. This
      ensures that any JIT data is also freed.
For a program that may be linked with pre-8.20 versions of PCRE, you can insert
  #ifndef PCRE_STUDY_JIT_COMPILE
  #define PCRE_STUDY_JIT_COMPILE 0
  #endif
so that no option is passed to pcre_study(), and then use something like this to free the study data:
  #ifdef PCRE_CONFIG_JIT
      pcre_free_study(study_ptr);
  #else
      pcre_free(study_ptr);
  #endif
PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for complete matches. If you want to run partial matches using the PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of pcre_exec(), you should set one or both of the following options in addition to, or instead of, PCRE_STUDY_JIT_COMPILE when you call pcre_study():
  PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
  PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
The JIT compiler generates different optimized code for each of the three modes (normal, soft partial, hard partial). When pcre_exec() is called, the appropriate code is run if it is available. Otherwise, the pattern is matched using interpretive code.

In some circumstances you may need to call additional functions. These are described in the section entitled "Controlling the JIT stack" below.

If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ignored, and no JIT data is created. Otherwise, the compiled pattern is passed to the JIT compiler, which turns it into machine code that executes much faster than the normal interpretive code. When pcre_exec() is passed a pcre_extra block containing a pointer to JIT code of the appropriate mode (normal or hard/soft partial), it obeys that code instead of running the interpreter. The result is identical, but the compiled JIT code runs much faster.

There are some pcre_exec() options that are not supported for JIT execution. There are also some pattern items that JIT cannot handle. Details are given below. In both cases, execution automatically falls back to the interpretive code. If you want to know whether JIT was actually used for a particular match, you should arrange for a JIT callback function to be set up as described in the section entitled "Controlling the JIT stack" below, even if you do not need to supply a non-default JIT stack. Such a callback function is called whenever JIT code is about to be obeyed. If the execution options are not right for JIT execution, the callback function is not obeyed.

If the JIT compiler finds an unsupported item, no JIT data is generated. You can find out if JIT execution is available after studying a pattern by calling pcre_fullinfo() with the PCRE_INFO_JIT option. A result of 1 means that JIT compilation was successful. A result of 0 means that JIT support is not available, or the pattern was not studied with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to handle the pattern.

Once a pattern has been studied, with or without JIT, it can be used as many times as you like for matching different subject strings.


UNSUPPORTED OPTIONS AND PATTERN ITEMS

The only pcre_exec() options that are supported for JIT execution are PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT.

The unsupported pattern items are:

  \C             match a single byte; not supported in UTF-8 mode
  (?Cn)          callouts
  (*PRUNE)       )
  (*SKIP)        ) backtracking control verbs
  (*THEN)        )
Support for some of these may be added in future.


RETURN VALUES FROM JIT EXECUTION

When a pattern is matched using JIT execution, the return values are the same as those given by the interpretive pcre_exec() code, with the addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means that the memory used for the JIT stack was insufficient. See "Controlling the JIT stack" below for a discussion of JIT stack usage. For compatibility with the interpretive pcre_exec() code, no more than two-thirds of the ovector argument is used for passing back captured substrings.

The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if searching a very large pattern tree goes on for too long, as it is in the same circumstance when JIT is not used, but the details of exactly what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error code is never returned by JIT execution.


SAVING AND RESTORING COMPILED PATTERNS

The code that is generated by the JIT compiler is architecture-specific, and is also position dependent. For those reasons it cannot be saved (in a file or database) and restored later like the bytecode and other data of a compiled pattern. Saving and restoring compiled patterns is not something many people do. More detail about this facility is given in the pcreprecompile documentation. It should be possible to run pcre_study() on a saved and restored pattern, and thereby recreate the JIT data, but because JIT compilation uses significant resources, it is probably not worth doing this; you might as well recompile the original pattern.


CONTROLLING THE JIT STACK

When the compiled JIT code runs, it needs a block of memory to use as a stack. By default, it uses 32K on the machine stack. However, some large or complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack. Three functions are provided for managing blocks of memory for use as JIT stacks. There is further discussion about the use of JIT stacks in the section entitled "JIT stack FAQ" below.

The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments are a starting size and a maximum size, and it returns a pointer to an opaque structure of type pcre_jit_stack, or NULL if there is an error. The pcre_jit_stack_free() function can be used to free a stack that is no longer needed. (For the technically minded: the address space is allocated by mmap or VirtualAlloc.)

JIT uses far less memory for recursion than the interpretive code, and a maximum stack size of 512K to 1M should be more than enough for any pattern.

The pcre_assign_jit_stack() function specifies which stack JIT code should use. Its arguments are as follows:

  pcre_extra         *extra
  pcre_jit_callback  callback
  void               *data
The extra argument must be the result of studying a pattern with PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other two options:
  (1) If callback is NULL and data is NULL, an internal 32K block
      on the machine stack is used.

  (2) If callback is NULL and data is not NULL, data must be
      a valid JIT stack, the result of calling pcre_jit_stack_alloc().

  (3) If callback is not NULL, it must point to a function that is
      called with data as an argument at the start of matching, in
      order to set up a JIT stack. If the return from the callback
      function is NULL, the internal 32K stack is used; otherwise the
      return value must be a valid JIT stack, the result of calling
      pcre_jit_stack_alloc().
A callback function is obeyed whenever JIT code is about to be run; it is not obeyed when pcre_exec() is called with options that are incompatible for JIT execution. A callback function can therefore be used to determine whether a match operation was executed by JIT or by the interpreter.

You may safely use the same JIT stack for more than one pattern (either by assigning directly or by callback), as long as the patterns are all matched sequentially in the same thread. In a multithread application, if you do not specify a JIT stack, or if you assign or pass back NULL from a callback, that is thread-safe, because each thread has its own machine stack. However, if you assign or pass back a non-NULL JIT stack, this must be a different stack for each thread so that the application is thread-safe.

Strictly speaking, even more is allowed. You can assign the same non-NULL stack to any number of patterns as long as they are not used for matching by multiple threads at the same time. For example, you can assign the same stack to all compiled patterns, and use a global mutex in the callback to wait until the stack is available for use. However, this is an inefficient solution, and not recommended.

This is a suggestion for how a multithreaded program that needs to set up non-default JIT stacks might operate:

  During thread initalization
    thread_local_var = pcre_jit_stack_alloc(...)

  During thread exit
    pcre_jit_stack_free(thread_local_var)

  Use a one-line callback function
    return thread_local_var
All the functions described in this section do nothing if JIT is not available, and pcre_assign_jit_stack() does nothing unless the extra argument is non-NULL and points to a pcre_extra block that is the result of a successful study with PCRE_STUDY_JIT_COMPILE etc.


JIT STACK FAQ

(1) Why do we need JIT stacks?

PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack where the local data of the current node is pushed before checking its child nodes. Allocating real machine stack on some platforms is difficult. For example, the stack chain needs to be updated every time if we extend the stack on PowerPC. Although it is possible, its updating time overhead decreases performance. So we do the recursion in memory.

(2) Why don't we simply allocate blocks of memory with malloc()?

Modern operating systems have a nice feature: they can reserve an address space instead of allocating memory. We can safely allocate memory pages inside this address space, so the stack could grow without moving memory data (this is important because of pointers). Thus we can allocate 1M address space, and use only a single memory page (usually 4K) if that is enough. However, we can still grow up to 1M anytime if needed.

(3) Who "owns" a JIT stack?

The owner of the stack is the user program, not the JIT studied pattern or anything else. The user program must ensure that if a stack is used by pcre_exec(), (that is, it is assigned to the pattern currently running), that stack must not be used by any other threads (to avoid overwriting the same memory area). The best practice for multithreaded programs is to allocate a stack for each thread, and return this stack through the JIT callback function.

(4) When should a JIT stack be freed?

You can free a JIT stack at any time, as long as it will not be used by pcre_exec() again. When you assign the stack to a pattern, only a pointer is set. There is no reference counting or any other magic. You can free the patterns and stacks in any order, anytime. Just do not call pcre_exec() with a pattern pointing to an already freed stack, as that will cause SEGFAULT. (Also, do not free a stack currently used by pcre_exec() in another thread). You can also replace the stack for a pattern at any time. You can even free the previous stack before assigning a replacement.

(5) Should I allocate/free a stack every time before/after calling pcre_exec()?

No, because this is too costly in terms of resources. However, you could implement some clever idea which release the stack if it is not used in let's say two minutes. The JIT callback can help to achive this without keeping a list of the currently JIT studied patterns.

(6) OK, the stack is for long term memory allocation. But what happens if a pattern causes stack overflow with a stack of 1M? Is that 1M kept until the stack is freed?

Especially on embedded sytems, it might be a good idea to release memory sometimes without freeing the stack. There is no API for this at the moment. Probably a function call which returns with the currently allocated memory for any stack and another which allows releasing memory (shrinking the stack) would be a good idea if someone needs this.

(7) This is too much of a headache. Isn't there any better solution for JIT stack handling?

No, thanks to Windows. If POSIX threads were used everywhere, we could throw out this complicated API.


EXAMPLE CODE

This is a single-threaded example that specifies a JIT stack without using a callback.

  int rc;
  int ovector[30];
  pcre *re;
  pcre_extra *extra;
  pcre_jit_stack *jit_stack;

  re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
  /* Check for errors */
  extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error);
  jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024);
  /* Check for error (NULL) */
  pcre_assign_jit_stack(extra, NULL, jit_stack);
  rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30);
  /* Check results */
  pcre_free(re);
  pcre_free_study(extra);
  pcre_jit_stack_free(jit_stack);


SEE ALSO

pcreapi(3)


AUTHOR

Philip Hazel (FAQ by Zoltan Herczeg)
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 04 May 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_jit_stack_free.html0000644000222100022210000000226011775533017015700 00000000000000 pcre_jit_stack_free specification

pcre_jit_stack_free man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

void pcre_jit_stack_free(pcre_jit_stack *stack);

void pcre16_jit_stack_free(pcre16_jit_stack *stack);


DESCRIPTION

This function is used to free a JIT stack that was created by pcre[16]_jit_stack_alloc() when it is no longer needed. For more details, see the pcrejit page.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrepattern.html0000644000222100022210000036346411775533020014254 00000000000000 pcrepattern specification

pcrepattern man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


PCRE REGULAR EXPRESSION DETAILS

The syntax and semantics of the regular expressions that are supported by PCRE are described in detail below. There is a quick-reference syntax summary in the pcresyntax page. PCRE tries to match Perl syntax and semantics as closely as it can. PCRE also supports some alternative regular expression syntax (which does not conflict with the Perl syntax) in order to provide some compatibility with regular expressions in Python, .NET, and Oniguruma.

Perl's regular expressions are described in its own documentation, and regular expressions in general are covered in a number of books, some of which have copious examples. Jeffrey Friedl's "Mastering Regular Expressions", published by O'Reilly, covers regular expressions in great detail. This description of PCRE's regular expressions is intended as reference material.

The original operation of PCRE was on strings of one-byte characters. However, there is now also support for UTF-8 strings in the original library, and a second library that supports 16-bit and UTF-16 character strings. To use these features, PCRE must be built to include appropriate support. When using UTF strings you must either call the compiling function with the PCRE_UTF8 or PCRE_UTF16 option, or the pattern must start with one of these special sequences:

  (*UTF8)
  (*UTF16)
Starting a pattern with such a sequence is equivalent to setting the relevant option. This feature is not Perl-compatible. How setting a UTF mode affects pattern matching is mentioned in several places below. There is also a summary of features in the pcreunicode page.

Another special sequence that may appear at the start of a pattern or in combination with (*UTF8) or (*UTF16) is:

  (*UCP)
This has the same effect as setting the PCRE_UCP option: it causes sequences such as \d and \w to use Unicode properties to determine character types, instead of recognizing only characters with codes less than 128 via a lookup table.

If a pattern starts with (*NO_START_OPT), it has the same effect as setting the PCRE_NO_START_OPTIMIZE option either at compile or matching time. There are also some more of these special sequences that are concerned with the handling of newlines; they are described below.

The remainder of this document discusses the patterns that are supported by PCRE when one its main matching functions, pcre_exec() (8-bit) or pcre16_exec() (16-bit), is used. PCRE also has alternative matching functions, pcre_dfa_exec() and pcre16_dfa_exec(), which match using a different algorithm that is not Perl-compatible. Some of the features discussed below are not available when DFA matching is used. The advantages and disadvantages of the alternative functions, and how they differ from the normal functions, are discussed in the pcrematching page.


NEWLINE CONVENTIONS

PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (linefeed) character, the two-character sequence CRLF, any of the three preceding, or any Unicode newline sequence. The pcreapi page has further discussion about newlines, and shows how to set the newline convention in the options arguments for the compiling and matching functions.

It is also possible to specify a newline convention by starting a pattern string with one of the following five sequences:

  (*CR)        carriage return
  (*LF)        linefeed
  (*CRLF)      carriage return, followed by linefeed
  (*ANYCRLF)   any of the three above
  (*ANY)       all Unicode newline sequences
These override the default and the options given to the compiling function. For example, on a Unix system where LF is the default newline sequence, the pattern
  (*CR)a.b
changes the convention to CR. That pattern matches "a\nb" because LF is no longer a newline. Note that these special settings, which are not Perl-compatible, are recognized only at the very start of a pattern, and that they must be in upper case. If more than one of them is present, the last one is used.

The newline convention affects the interpretation of the dot metacharacter when PCRE_DOTALL is not set, and also the behaviour of \N. However, it does not affect what the \R escape sequence matches. By default, this is any Unicode newline sequence, for Perl compatibility. However, this can be changed; see the description of \R in the section entitled "Newline sequences" below. A change of \R setting can be combined with a change of newline convention.


CHARACTERS AND METACHARACTERS

A regular expression is a pattern that is matched against a subject string from left to right. Most characters stand for themselves in a pattern, and match the corresponding characters in the subject. As a trivial example, the pattern

  The quick brown fox
matches a portion of a subject string that is identical to itself. When caseless matching is specified (the PCRE_CASELESS option), letters are matched independently of case. In a UTF 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 compiled 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 support.

The power of regular expressions comes from the ability to include alternatives and repetitions in the pattern. These are encoded in the pattern by the use of metacharacters, which do not stand for themselves but instead are interpreted in some special way.

There are two different sets of metacharacters: those that are recognized anywhere in the pattern except within square brackets, and those that are recognized within square brackets. Outside square brackets, the metacharacters are as follows:

  \      general escape character with several uses
  ^      assert start of string (or line, in multiline mode)
  $      assert end of string (or line, in multiline mode)
  .      match any character except newline (by default)
  [      start character class definition
  |      start of alternative branch
  (      start subpattern
  )      end subpattern
  ?      extends the meaning of (
         also 0 or 1 quantifier
         also quantifier minimizer
  *      0 or more quantifier
  +      1 or more quantifier
         also "possessive quantifier"
  {      start min/max quantifier
Part of a pattern that is in square brackets is called a "character class". In a character class the only metacharacters are:
  \      general escape character
  ^      negate the class, but only if the first character
  -      indicates character range
  [      POSIX character class (only if followed by POSIX syntax)
  ]      terminates the character class
The following sections describe the use of each of the metacharacters.


BACKSLASH

The backslash character has several uses. Firstly, if it is followed by a character that is not a number or a letter, it takes away any special meaning that character may have. This use of backslash as an escape character applies both inside and outside character classes.

For example, if you want to match a * character, you write \* in the pattern. This escaping action applies whether or not the following character would otherwise be interpreted as a metacharacter, so it is always safe to precede a non-alphanumeric with backslash to specify that it stands for itself. In particular, if you want to match a backslash, you write \\.

In a UTF mode, only ASCII numbers and letters have any special meaning after a backslash. All other characters (in particular, those whose codepoints are greater than 127) are treated as literals.

If a pattern is compiled with the PCRE_EXTENDED option, white space in the pattern (other than in a character class) and characters between a # outside a character class and the next newline are ignored. An escaping backslash can be used to include a white space or # character as part of the pattern.

If you want to remove the special meaning from a sequence of characters, you can do so by putting them between \Q and \E. This is different from Perl in that $ and @ are handled as literals in \Q...\E sequences in PCRE, whereas in Perl, $ and @ cause variable interpolation. Note the following examples:

  Pattern            PCRE matches   Perl matches

  \Qabc$xyz\E        abc$xyz        abc followed by the contents of $xyz
  \Qabc\$xyz\E       abc\$xyz       abc\$xyz
  \Qabc\E\$\Qxyz\E   abc$xyz        abc$xyz
The \Q...\E sequence is recognized both inside and outside character classes. An isolated \E that is not preceded by \Q is ignored. If \Q is not followed by \E later in the pattern, the literal interpretation continues to the end of the pattern (that is, \E is assumed at the end). If the isolated \Q is inside a character class, this causes an error, because the character class is not terminated.


Non-printing characters

A second use of backslash provides a way of encoding non-printing characters in patterns in a visible manner. There is no restriction on the appearance of non-printing characters, apart from the binary zero that terminates a pattern, but when a pattern is being prepared by text editing, it is often easier to use one of the following escape sequences than the binary character it represents:

  \a        alarm, that is, the BEL character (hex 07)
  \cx       "control-x", where x is any ASCII character
  \e        escape (hex 1B)
  \f        form feed (hex 0C)
  \n        linefeed (hex 0A)
  \r        carriage return (hex 0D)
  \t        tab (hex 09)
  \ddd      character with octal code ddd, or back reference
  \xhh      character with hex code hh
  \x{hhh..} character with hex code hhh.. (non-JavaScript mode)
  \uhhhh    character with hex code hhhh (JavaScript mode only)
The precise effect of \cx is as follows: if x is a lower case letter, it is converted to upper case. Then bit 6 of the character (hex 40) is inverted. Thus \cz becomes hex 1A (z is 7A), but \c{ becomes hex 3B ({ is 7B), while \c; becomes hex 7B (; is 3B). If the byte following \c has a value greater than 127, a compile-time error occurs. This locks out non-ASCII characters in all modes. (When PCRE is compiled in EBCDIC mode, all byte values are valid. A lower case letter is converted to upper case, and then the 0xc0 bits are flipped.)

By default, after \x, from zero to two hexadecimal digits are read (letters can be in upper or lower case). Any number of hexadecimal digits may appear between \x{ and }, but the character code is constrained as follows:

  8-bit non-UTF mode    less than 0x100
  8-bit UTF-8 mode      less than 0x10ffff and a valid codepoint
  16-bit non-UTF mode   less than 0x10000
  16-bit UTF-16 mode    less than 0x10ffff and a valid codepoint
Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called "surrogate" codepoints).

If characters other than hexadecimal digits appear between \x{ and }, or if there is no terminating }, this form of escape is not recognized. Instead, the initial \x will be interpreted as a basic hexadecimal escape, with no following digits, giving a character whose value is zero.

If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x is as just described only when it is followed by two hexadecimal digits. Otherwise, it matches a literal "x" character. In JavaScript mode, support for code points greater than 256 is provided by \u, which must be followed by four hexadecimal digits; otherwise it matches a literal "u" character. Character codes specified by \u in JavaScript mode are constrained in the same was as those specified by \x in non-JavaScript mode.

Characters whose value is less than 256 can be defined by either of the two syntaxes for \x (or by \u in JavaScript mode). There is no difference in the way they are handled. For example, \xdc is exactly the same as \x{dc} (or \u00dc in JavaScript mode).

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 complicated. Outside a character class, PCRE reads it and any following digits 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 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 uses them to generate a data character. Any subsequent digits stand for themselves. The value of the character is constrained in the same way as characters specified in hexadecimal. For example:

  \040   is another way of writing a space
  \40    is the same, provided there are fewer than 40 previous capturing subpatterns
  \7     is always a back reference
  \11    might be a back reference, or another way of writing a tab
  \011   is always a tab
  \0113  is a tab followed by the character "3"
  \113   might be a back reference, otherwise the character with octal code 113
  \377   might be a back reference, otherwise the value 255 (decimal)
  \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 leading zero, because no more than three octal digits are ever read.

All the sequences that define a single character value can be used both inside and outside character classes. In addition, inside a character class, \b is interpreted as the backspace character (hex 08).

\N is not allowed in a character class. \B, \R, and \X are not special inside a character class. Like other unrecognized escape sequences, they are treated as the literal characters "B", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is set. Outside a character class, these sequences have different meanings.


Unsupported escape sequences

In Perl, the sequences \l, \L, \u, and \U are recognized by its string handler and used to modify the case of following characters. By default, PCRE does not support these escape sequences. However, if the PCRE_JAVASCRIPT_COMPAT option is set, \U matches a "U" character, and \u can be used to define a character by code point, as described in the previous section.


Absolute and relative back references

The sequence \g followed by an unsigned or a negative number, optionally enclosed in braces, is an absolute or relative back reference. A named back reference can be coded as \g{name}. Back references are discussed later, following the discussion of parenthesized subpatterns.


Absolute and relative subroutine calls

For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or a number enclosed either in angle brackets or single quotes, is an alternative syntax for referencing a subpattern as a "subroutine". Details are discussed later. Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not synonymous. The former is a back reference; the latter is a subroutine call.


Generic character types

Another use of backslash is for specifying generic character types:

  \d     any decimal digit
  \D     any character that is not a decimal digit
  \h     any horizontal white space character
  \H     any character that is not a horizontal white space character
  \s     any white space character
  \S     any character that is not a white space character
  \v     any vertical white space character
  \V     any character that is not a vertical white space character
  \w     any "word" character
  \W     any "non-word" character
There is also the single sequence \N, which matches a non-newline character. This is the same as the "." metacharacter when PCRE_DOTALL is not set. Perl also uses \N to match characters by name; PCRE does not support this.

Each pair of lower and upper case escape sequences partitions the complete set of characters into two disjoint sets. Any given character matches one, and only one, of each pair. The sequences can appear both inside and outside character classes. They each match one character of the appropriate type. If the current matching point is at the end of the subject string, all of them fail, because there is no character to match.

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). If "use locale;" is included in a Perl script, \s may match the VT character. In PCRE, it never does.

A "word" character is an underscore or any character that is a letter or digit. By default, the definition of letters and digits is controlled by PCRE's low-valued character tables, and may vary if locale-specific matching is taking place (see "Locale support" in the pcreapi page). For example, in a French locale such as "fr_FR" in Unix-like systems, or "french" in Windows, some character codes greater than 128 are used for accented letters, and these are then matched by \w. The use of locales with Unicode is discouraged.

By default, in a UTF mode, characters with values greater than 128 never match \d, \s, or \w, and always match \D, \S, and \W. These sequences retain their original meanings from before UTF support was available, mainly for efficiency reasons. However, if PCRE is compiled with Unicode property support, and the PCRE_UCP option is set, the behaviour is changed so that Unicode properties are used to determine character types, as follows:

  \d  any character that \p{Nd} matches (decimal digit)
  \s  any character that \p{Z} matches, plus HT, LF, FF, CR
  \w  any character that \p{L} or \p{N} matches, plus underscore
The upper case escapes match the inverse sets of characters. Note that \d matches only decimal digits, whereas \w matches any Unicode digit, as well as any Unicode letter, and underscore. Note also that PCRE_UCP affects \b, and \B because they are defined in terms of \w and \W. Matching these sequences is noticeably slower when PCRE_UCP is set.

The sequences \h, \H, \v, and \V are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII characters by default, these always match certain high-valued codepoints, whether or not PCRE_UCP is set. The horizontal space characters are:

  U+0009     Horizontal tab
  U+0020     Space
  U+00A0     Non-break space
  U+1680     Ogham space mark
  U+180E     Mongolian vowel separator
  U+2000     En quad
  U+2001     Em quad
  U+2002     En space
  U+2003     Em space
  U+2004     Three-per-em space
  U+2005     Four-per-em space
  U+2006     Six-per-em space
  U+2007     Figure space
  U+2008     Punctuation space
  U+2009     Thin space
  U+200A     Hair space
  U+202F     Narrow no-break space
  U+205F     Medium mathematical space
  U+3000     Ideographic space
The vertical space characters are:
  U+000A     Linefeed
  U+000B     Vertical tab
  U+000C     Form feed
  U+000D     Carriage return
  U+0085     Next line
  U+2028     Line separator
  U+2029     Paragraph separator
In 8-bit, non-UTF-8 mode, only the characters with codepoints less than 256 are relevant.


Newline sequences

Outside a character class, by default, the escape sequence \R matches any Unicode newline sequence. In 8-bit non-UTF-8 mode \R is equivalent to the following:

  (?>\r\n|\n|\x0b|\f|\r|\x85)
This is an example of an "atomic group", details of which are given below. This particular group matches either the two-character sequence CR followed by LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab, U+000B), FF (form feed, U+000C), CR (carriage return, U+000D), or NEL (next line, U+0085). The two-character sequence is treated as a single unit that cannot be split.

In other modes, two additional characters whose codepoints are greater than 255 are added: LS (line separator, U+2028) and PS (paragraph separator, U+2029). Unicode character property support is not needed for these characters to be recognized.

It is possible to restrict \R to match only CR, LF, or CRLF (instead of the complete set of Unicode line endings) by setting the option PCRE_BSR_ANYCRLF either at compile time or when the pattern is matched. (BSR is an abbrevation for "backslash R".) This can be made the default when PCRE is built; if this is the case, the other behaviour can be requested via the PCRE_BSR_UNICODE option. It is also possible to specify these settings by starting a pattern string with one of the following sequences:

  (*BSR_ANYCRLF)   CR, LF, or CRLF only
  (*BSR_UNICODE)   any Unicode newline sequence
These override the default and the options given to the compiling function, but they can themselves be overridden by options given to a matching function. Note that these special settings, which are not Perl-compatible, are recognized only at the very start of a pattern, and that they must be in upper case. If more than one of them is present, the last one is used. They can be combined with a change of newline convention; for example, a pattern can start with:
  (*ANY)(*BSR_ANYCRLF)
They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special sequences. Inside a character class, \R is treated as an unrecognized escape sequence, and so matches the letter "R" by default, but causes an error if PCRE_EXTRA is set.


Unicode character properties

When PCRE is built with Unicode character property support, three additional escape sequences that match characters with specific properties are available. When in 8-bit non-UTF-8 mode, these sequences are of course limited to testing characters whose codepoints are less than 256, but they do work in this mode. The extra escape sequences are:

  \p{xx}   a character with the xx property
  \P{xx}   a character without the xx property
  \X       an extended Unicode sequence
The property names represented by xx above are limited to the Unicode script names, the general category properties, "Any", which matches any character (including newline), and some special PCRE properties (described in the next section). Other Perl properties such as "InMusicalSymbols" are not currently supported by PCRE. Note that \P{Any} does not match any characters, so always causes a match failure.

Sets of Unicode characters are defined as belonging to certain scripts. A character from one of these sets can be matched using a script name. For example:

  \p{Greek}
  \P{Han}
Those that are not part of an identified script are lumped together as "Common". The current list of scripts is:

Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi.

Each character has exactly one Unicode general category property, specified by a two-letter abbreviation. For compatibility with Perl, negation can be specified by including a circumflex between the opening brace and the property name. For example, \p{^Lu} is the same as \P{Lu}.

If only one letter is specified with \p or \P, it includes all the general category properties that start with that letter. In this case, in the absence of negation, the curly brackets in the escape sequence are optional; these two examples have the same effect:

  \p{L}
  \pL
The following general category property codes are supported:
  C     Other
  Cc    Control
  Cf    Format
  Cn    Unassigned
  Co    Private use
  Cs    Surrogate

  L     Letter
  Ll    Lower case letter
  Lm    Modifier letter
  Lo    Other letter
  Lt    Title case letter
  Lu    Upper case letter

  M     Mark
  Mc    Spacing mark
  Me    Enclosing mark
  Mn    Non-spacing mark

  N     Number
  Nd    Decimal number
  Nl    Letter number
  No    Other number

  P     Punctuation
  Pc    Connector punctuation
  Pd    Dash punctuation
  Pe    Close punctuation
  Pf    Final punctuation
  Pi    Initial punctuation
  Po    Other punctuation
  Ps    Open punctuation

  S     Symbol
  Sc    Currency symbol
  Sk    Modifier symbol
  Sm    Mathematical symbol
  So    Other symbol

  Z     Separator
  Zl    Line separator
  Zp    Paragraph separator
  Zs    Space separator
The special property L& is also supported: it matches a character that has the Lu, Ll, or Lt property, in other words, a letter that is not classified as a modifier or "other".

The Cs (Surrogate) property applies only to characters in the range U+D800 to U+DFFF. Such characters are not valid in Unicode strings and so cannot be tested by PCRE, unless UTF validity checking has been turned off (see the discussion of PCRE_NO_UTF8_CHECK and PCRE_NO_UTF16_CHECK in the pcreapi page). Perl does not support the Cs property.

The long synonyms for property names that Perl supports (such as \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) property. Instead, this property is assumed for any code point that is not in the Unicode table.

Specifying caseless matching does not affect these escape sequences. For example, \p{Lu} always matches only upper case letters.

The \X escape matches any number of Unicode characters that form an extended Unicode sequence. \X is equivalent to

  (?>\PM\pM*)
That is, it matches a character without the "mark" property, followed by zero or more characters with the "mark" property, and treats the sequence as an atomic group (see below). Characters with the "mark" property are typically accents that affect the preceding character. None of them have codepoints less than 256, so in 8-bit non-UTF-8 mode \X matches any one character.

Note that recent versions of Perl have changed \X to match what Unicode calls an "extended grapheme cluster", which has a more complicated definition.

Matching characters by Unicode property is not fast, because PCRE has to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \d and \w do not use Unicode properties in PCRE by default, though you can make them do so by setting the PCRE_UCP option or by starting the pattern with (*UCP).


PCRE's additional properties

As well as the standard Unicode properties described in the previous section, PCRE supports four more that make it possible to convert traditional escape sequences such as \w and \s and POSIX character classes to use Unicode properties. PCRE uses these non-standard, non-Perl properties internally when PCRE_UCP is set. They are:

  Xan   Any alphanumeric character
  Xps   Any POSIX space character
  Xsp   Any Perl space character
  Xwd   Any Perl "word" character
Xan matches characters that have either the L (letter) or the N (number) property. Xps matches the characters tab, linefeed, vertical tab, form feed, or carriage return, and any other character that has the Z (separator) property. Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the same characters as Xan, plus underscore.


Resetting the match start

The escape sequence \K causes any previously matched characters not to be included in the final matched sequence. For example, the pattern:

  foo\Kbar
matches "foobar", but reports that it has matched "bar". This feature is similar to a lookbehind assertion (described below). However, in this case, the part of the subject before the real match does not have to be of fixed length, as lookbehind assertions do. The use of \K does not interfere with the setting of captured substrings. For example, when the pattern
  (foo)\Kbar
matches "foobar", the first substring is still set to "foo".

Perl documents that the use of \K within assertions is "not well defined". In PCRE, \K is acted upon when it occurs inside positive assertions, but is ignored in negative assertions.


Simple assertions

The final use of backslash is for certain simple assertions. An assertion specifies a condition that has to be met at a particular point in a match, without consuming any characters from the subject string. The use of subpatterns for more complicated assertions is described below. The backslashed assertions are:

  \b     matches at a word boundary
  \B     matches when not at a word boundary
  \A     matches at the start of the subject
  \Z     matches at the end of the subject
          also matches before a newline at the end of the subject
  \z     matches only at the end of the subject
  \G     matches at the first matching position in the subject
Inside a character class, \b has a different meaning; it matches the backspace character. If any other of these assertions appears in a character class, by default it matches the corresponding literal character (for example, \B matches the letter B). However, if the PCRE_EXTRA option is set, an "invalid escape sequence" error is generated instead.

A word boundary is a position in the subject string where the current character and the previous character do not both match \w or \W (i.e. one matches \w and the other matches \W), or the start or end of the string if the first or last character matches \w, respectively. In a UTF mode, the meanings of \w and \W can be changed by setting the PCRE_UCP option. When this is done, it also affects \b and \B. Neither PCRE nor Perl has a separate "start of word" or "end of word" metasequence. However, whatever follows \b normally determines which it is. For example, the fragment \ba matches "a" at the start of a word.

The \A, \Z, and \z assertions differ from the traditional circumflex and dollar (described in the next section) in that they only ever match at the very start and end of the subject string, whatever options are set. Thus, they are independent of multiline mode. These three assertions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which affect only the behaviour of the circumflex and dollar metacharacters. However, if the startoffset argument of pcre_exec() is non-zero, indicating 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 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 arguments, you can mimic Perl's /g option, and it is in this kind of implementation where \G can be useful.

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 at a time, it cannot reproduce this behaviour.

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.


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 argument 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 subject, 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 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, 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) AND \N

Outside a character class, a dot in the pattern matches any one character in the subject string except (by default) a character that signifies the end of a line.

When a line ending is defined as a single character, dot never matches that character; when the two-character sequence CRLF is used, dot does not match CR if it is immediately followed by LF, but otherwise it matches all characters (including isolated CRs and LFs). When any Unicode line endings are being recognized, dot does not match CR or LF or any of the other line ending characters.

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 the two-character sequence CRLF is present in the subject string, it takes two dots to match it.

The handling of dot is entirely independent of the handling of circumflex and dollar, the only relationship being that they both involve newlines. Dot has no special meaning in a character class.

The escape sequence \N behaves like a dot, except that it is not affected by the PCRE_DOTALL option. In other words, it matches any character except one that signifies the end of a line. Perl also uses \N to match characters by name; PCRE does not support this.


MATCHING A SINGLE DATA UNIT

Outside a character class, the escape sequence \C matches any one data unit, whether or not a UTF mode is set. In the 8-bit library, one data unit is one byte; in the 16-bit library it is a 16-bit unit. Unlike a dot, \C always matches line-ending characters. The feature is provided in Perl in order to match individual bytes in UTF-8 mode, but it is unclear how it can usefully be used. Because \C breaks up characters into individual data units, matching one unit with \C in a UTF mode means that the rest of the string may start with a malformed UTF character. This has undefined results, because PCRE assumes that it is dealing with valid UTF strings (and by default it checks this at the start of processing unless the PCRE_NO_UTF8_CHECK or PCRE_NO_UTF16_CHECK option is used).

PCRE does not allow \C to appear in lookbehind assertions (described below) in a UTF mode, because this would make it impossible to calculate the length of the lookbehind.

In general, the \C escape sequence is best avoided. However, one way of using it that avoids the problem of malformed UTF characters is to use a lookahead to check the length of the next character, as in this pattern, which could be used with a UTF-8 string (ignore white space and line breaks):

  (?| (?=[\x00-\x7f])(\C) |
      (?=[\x80-\x{7ff}])(\C)(\C) |
      (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) |
      (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C))
A group that starts with (?| resets the capturing parentheses numbers in each alternative (see "Duplicate Subpattern Numbers" below). The assertions at the start of each branch check the next UTF-8 character for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The character's individual bytes are then captured by the appropriate number of groups.


SQUARE BRACKETS AND CHARACTER CLASSES

An opening square bracket introduces a character class, terminated by a closing square bracket. A closing square bracket on its own is not special by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, a lone closing square bracket causes a compile-time error. If a closing square bracket is required as a member of the class, it should be the first data character in the class (after an initial circumflex, if present) or escaped with a backslash.

A character class matches a single character in the subject. In a UTF mode, the character may be more than one data unit long. A matched character must be in the set of characters defined by the class, unless the first character in the class definition is a circumflex, in which case the subject character must not be in the set defined by the class. If a circumflex is actually required as a member of the class, ensure it is not the first character, or escape it with a backslash.

For example, the character class [aeiou] matches any lower case vowel, while [^aeiou] matches any character that is not a lower case vowel. Note that a circumflex is just a convenient notation for specifying the characters that are in the class by enumerating those that are not. A class that starts with a circumflex is not an assertion; it still consumes a character from the subject string, and therefore it fails if the current pointer is at the end of the string.

In UTF-8 (UTF-16) mode, characters with values greater than 255 (0xffff) can be included in a class as a literal string of data units, or by using the \x{ escaping mechanism.

When caseless matching is set, any letters in a class represent both their upper case and lower case versions, so for example, a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a caseful version would. In a UTF 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 compiled with Unicode property support, but not otherwise. If you want to use caseless matching in a UTF mode for characters 128 and above, you must ensure that PCRE is compiled with Unicode property support as well as with UTF support.

Characters that might indicate line breaks 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 characters in a character class. For example, [d-m] matches any letter between d and m, inclusive. If a minus character is required in a class, it must be escaped with a backslash or appear in a position where it cannot be interpreted as indicating a range, typically as the first or last character in the class.

It is not possible to have the literal character "]" as the end character of a range. A pattern such as [W-]46] is interpreted as a class of two characters ("W" and "-") followed by a literal string "46]", so it would match "W46]" or "-46]". However, if the "]" is escaped with a backslash it is interpreted as the end of range, so [W-\]46] is interpreted as a class containing a range followed by two other characters. The octal or hexadecimal representation of "]" can also be used to end a range.

Ranges operate in the collating sequence of character values. They can also be used for characters specified numerically, for example [\000-\037]. Ranges can include any characters that are valid for the current mode.

If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character tables for a French locale are in use, [\xc8-\xcb] matches accented E characters in both cases. In UTF modes, PCRE supports the concept of case for characters with values greater than 128 only when it is compiled with Unicode property support.

The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V, \w, and \W may appear in a character class, and add the characters that they match to the class. For example, [\dABCDEF] matches any hexadecimal digit. In UTF modes, the PCRE_UCP option affects the meanings of \d, \s, \w and their upper case partners, just as it does when they appear outside a character class, as described in the section entitled "Generic character types" above. The escape sequence \b has a different meaning inside a character class; it matches the backspace character. The sequences \B, \N, \R, and \X are not special inside a character class. Like any other unrecognized escape sequences, they are treated as the literal characters "B", "N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is set.

A circumflex can conveniently be used with the upper case character types to specify a more restricted set of characters than the matching lower case type. For example, the class [^\W_] matches any letter or digit, but not underscore, whereas [\w] includes underscore. A positive character class should be read as "something OR something OR ..." and a negative class as "NOT something AND NOT something AND NOT ...".

The only metacharacters that are recognized in character classes are backslash, hyphen (only where it can be interpreted as specifying a range), circumflex (only at the start), opening square bracket (only when it can be interpreted as introducing a POSIX class name - see the next section), and the terminating closing square bracket. However, escaping other non-alphanumeric characters does no harm.


POSIX CHARACTER CLASSES

Perl supports the POSIX notation for character classes. This uses names enclosed by [: and :] within the enclosing square brackets. PCRE also supports this notation. For example,

  [01[:alpha:]%]
matches "0", "1", any alphabetic character, or "%". The supported class names are:
  alnum    letters and digits
  alpha    letters
  ascii    character codes 0 - 127
  blank    space or tab only
  cntrl    control characters
  digit    decimal digits (same as \d)
  graph    printing characters, excluding space
  lower    lower case letters
  print    printing characters, including space
  punct    printing characters, excluding letters and digits and space
  space    white space (not quite the same as \s)
  upper    upper case letters
  word     "word" characters (same as \w)
  xdigit   hexadecimal digits
The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), and space (32). Notice that this list includes the VT character (code 11). This makes "space" different to \s, which does not include VT (for Perl compatibility).

The name "word" is a Perl extension, and "blank" is a GNU extension from Perl 5.8. Another Perl extension is negation, which is indicated by a ^ character after the colon. For example,

  [12[:^digit:]]
matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered.

By default, in UTF modes, characters with values greater than 128 do not match any of the POSIX character classes. However, if the PCRE_UCP option is passed to pcre_compile(), some of the classes are changed so that Unicode character properties are used. This is achieved by replacing the POSIX classes by other sequences, as follows:

  [:alnum:]  becomes  \p{Xan}
  [:alpha:]  becomes  \p{L}
  [:blank:]  becomes  \h
  [:digit:]  becomes  \p{Nd}
  [:lower:]  becomes  \p{Ll}
  [:space:]  becomes  \p{Xps}
  [:upper:]  becomes  \p{Lu}
  [:word:]   becomes  \p{Xwd}
Negated versions, such as [:^alpha:] use \P instead of \p. The other POSIX classes are unchanged, and match only characters with code points less than 128.


VERTICAL BAR

Vertical bar characters are used to separate alternative patterns. For example, the pattern

  gilbert|sullivan
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 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

The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and PCRE_EXTENDED options (which are Perl-compatible) can be changed from within the pattern by a sequence of Perl option letters enclosed between "(?" and ")". The option letters are

  i  for PCRE_CASELESS
  m  for PCRE_MULTILINE
  s  for PCRE_DOTALL
  x  for PCRE_EXTENDED
For example, (?im) sets caseless, multiline matching. It is also possible to unset these options by preceding the letter with a hyphen, and a combined setting and unsetting such as (?im-sx), which sets PCRE_CASELESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, is also permitted. If a letter appears both before and after the hyphen, the option is unset.

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.

When one of these option changes occurs at top level (that is, not inside subpattern parentheses), the change applies to the remainder of the pattern that follows. If the change is placed right at the start of a pattern, PCRE extracts it into the global options (and it will therefore show up in data extracted by the pcre_fullinfo() function).

An option change within a subpattern (see below for a description of subpatterns) affects only that part of the subpattern that follows it, so

  (a(?i)b)c
matches abc and aBc and no other strings (assuming PCRE_CASELESS is not used). By this means, options can be made to have different settings in different parts of the pattern. Any changes made in one alternative do carry on into subsequent branches within the same subpattern. For example,
  (a(?i)b|c)
matches "ab", "aB", "c", and "C", even though when matching "C" the first branch is abandoned before the option setting. This is because the effects of option settings happen at compile time. There would be some very weird behaviour otherwise.

Note: There are other PCRE-specific options that can be set by the application when the compiling or matching functions are called. In some cases the pattern can contain special leading sequences such as (*CRLF) to override what the application has set or what has been defaulted. Details are given in the section entitled "Newline sequences" above. There are also the (*UTF8), (*UTF16), and (*UCP) leading sequences that can be used to set UTF and Unicode property modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, and the PCRE_UCP options, respectively.


SUBPATTERNS

Subpatterns are delimited by parentheses (round brackets), which can be nested. Turning part of a pattern into a subpattern does two things:

1. It localizes a set of alternatives. For example, the pattern

  cat(aract|erpillar|)
matches "cataract", "caterpillar", or "cat". Without the parentheses, it would match "cataract", "erpillar" or an 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 string that matched the subpattern is passed back to the caller via the ovector argument of the matching function. (This applies only to the traditional matching functions; the DFA matching functions do not support capturing.)

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 pattern

  the ((red|white) (king|queen))
the captured substrings are "red king", "red", and "king", and are numbered 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 capturing, 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.

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 "Saturday".


DUPLICATE SUBPATTERN NUMBERS

Perl 5.10 introduced a feature whereby each alternative in a subpattern uses the same numbers for its capturing parentheses. Such a subpattern starts with (?| and is itself a non-capturing subpattern. For example, consider this pattern:

  (?|(Sat)ur|(Sun))day
Because the two alternatives are inside a (?| group, both sets of capturing parentheses are numbered one. Thus, when the pattern matches, you can look at captured substring number one, whichever alternative matched. This construct is useful when you want to capture part, but not all, of one of a number of alternatives. Inside a (?| group, parentheses are numbered as usual, but the number is reset at the start of each branch. The numbers of any capturing parentheses that follow the subpattern start after the highest number used in any branch. The following example is taken from the Perl documentation. The numbers underneath show in which buffer the captured content will be stored.
  # before  ---------------branch-reset----------- after
  / ( a )  (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x
  # 1            2         2  3        2     3     4
A back reference to a numbered subpattern uses the most recent value that is set for that number by any subpattern. The following pattern matches "abcabc" or "defdef":
  /(?|(abc)|(def))\1/
In contrast, a subroutine call to a numbered subpattern always refers to the first one in the pattern with the given number. The following pattern matches "abcabc" or "defabc":
  /(?|(abc)|(def))(?1)/
If a condition test for a subpattern's having matched refers to a non-unique number, the test is true if any of the subpatterns of that number have matched.

An alternative approach to using this "branch reset" feature is to use duplicate named subpatterns, as described in the next section.


NAMED SUBPATTERNS

Identifying capturing parentheses by number is simple, but it can be very hard to keep track of the numbers in complicated regular expressions. Furthermore, if an expression is modified, the numbers may change. To help with this difficulty, PCRE supports the naming of subpatterns. This feature was not added to Perl until release 5.10. Python had the feature earlier, and PCRE introduced it at release 4.0, using the Python syntax. PCRE now supports both the Perl and the Python syntax. Perl allows identically numbered subpatterns to have different names, but PCRE does not.

In PCRE, a subpattern can be named in one of three ways: (?<name>...) or (?'name'...) as in Perl, or (?P<name>...) as in Python. References to capturing parentheses from other parts of the pattern, such as back references, recursion, and conditions, 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, exactly as if the names were not present. The PCRE API provides function calls for extracting the name-to-number translation table from a compiled pattern. There is also a convenience 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. (Duplicate names are also always permitted for subpatterns with the same number, set up as described in the previous section.) Duplicate names 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:

  (?<DN>Mon|Fri|Sun)(?:day)?|
  (?<DN>Tue)(?:sday)?|
  (?<DN>Wed)(?:nesday)?|
  (?<DN>Thu)(?:rsday)?|
  (?<DN>Sat)(?:urday)?
There are five capturing substrings, but only one is ever set after a match. (An alternative way of solving this problem is to use a "branch reset" subpattern, as described in the previous section.)

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 back reference to a non-unique named subpattern from elsewhere in the pattern, the one that corresponds to the first occurrence of the name is used. In the absence of duplicate numbers (see the previous section) this is the one with the lowest number. If you use a named reference in a condition test (see the section about conditions below), either to check whether a subpattern has matched, or to check for recursion, all subpatterns with the same name are tested. If the condition is true for any one of them, the overall condition is true. This is the same behaviour as testing by number. For further details of the interfaces for handling named subpatterns, see the pcreapi documentation.

Warning: You cannot use different names to distinguish between two subpatterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if different names are given to subpatterns with the same number. However, you can give the same name to subpatterns with the same number, even when PCRE_DUPNAMES is not set.


REPETITION

Repetition is specified by quantifiers, which can follow any of the following items:

  a literal data character
  the dot metacharacter
  the \C escape sequence
  the \X escape sequence
  the \R escape sequence
  an escape such as \d or \pL that matches a single character
  a character class
  a back reference (see next section)
  a parenthesized subpattern (including assertions)
  a subroutine call to a subpattern (recursive or otherwise)
The general repetition quantifier specifies a minimum and maximum number of permitted matches, by giving the two numbers in curly brackets (braces), separated by a comma. The numbers must be less than 65536, and the first must be less than or equal to the second. For example:
  z{2,4}
matches "zz", "zzz", or "zzzz". A closing brace on its own is not a special character. If the second number is omitted, but the comma is present, there is no upper limit; if the second number and the comma are both omitted, the quantifier specifies an exact number of required matches. Thus
  [aeiou]{3,}
matches at least 3 successive vowels, but may match many more, while
  \d{8}
matches exactly 8 digits. An opening curly bracket that appears in a position where a quantifier is not allowed, or one that does not match the syntax of a quantifier, is taken as a literal character. For example, {,6} is not a quantifier, but a literal string of four characters.

In UTF modes, quantifiers apply to characters rather than to individual data units. Thus, for example, \x{100}{2} matches two characters, each of which is represented by a two-byte sequence in a UTF-8 string. Similarly, \X{3} matches three Unicode extended sequences, each of which may be several data units long (and they may be of different lengths).

The quantifier {0} is permitted, causing the expression to behave as if the previous item and the quantifier were not present. This may be useful for subpatterns that are referenced as subroutines from elsewhere in the pattern (but see also the section entitled "Defining subpatterns for use by reference only" below). Items other than subpatterns that have a {0} quantifier are omitted from the compiled pattern.

For convenience, the three most common quantifiers have single-character abbreviations:

  *    is equivalent to {0,}
  +    is equivalent to {1,}
  ?    is equivalent to {0,1}
It is possible to construct infinite loops by following a subpattern that can match no characters with a quantifier that has no upper limit, for example:
  (a?)*
Earlier versions of Perl and PCRE used to give an error at compile time for such patterns. However, because there are cases where this can be useful, such patterns are now accepted, but if any repetition of the subpattern does in fact match no characters, the loop is forcibly broken.

By default, the quantifiers are "greedy", that is, they match as much as possible (up to the maximum number of permitted times), without causing the rest of the pattern to fail. The classic example of where this gives problems is in trying to match comments in C programs. These appear between /* and */ and within the comment, individual * and / characters may appear. An attempt to match C comments by applying the pattern

  /\*.*\*/
to the string
  /* first comment */  not comment  /* second comment */
fails, because it matches the entire string owing to the greediness of the .* item.

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

  /\*.*?\*/
does the right thing with the C comments. The meaning of the various quantifiers is not otherwise changed, just the preferred number of matches. Do not confuse this use of question mark with its use as a quantifier in its own right. Because it has two uses, it can sometimes appear doubled, as in
  \d??\d
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 that 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.

When a parenthesized subpattern is quantified with a minimum repeat count that is greater than 1 or with a limited maximum, more memory is required for the 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 dot 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 normally treats such a pattern as though it were preceded by \A.

In cases where it is known that the subject string contains no newlines, it is worth setting PCRE_DOTALL in order to obtain this optimization, or alternatively using ^ to indicate anchoring explicitly.

However, there is one situation where the optimization cannot be used. When .* is inside capturing parentheses that are the subject of a back reference elsewhere in the pattern, a match at the start may fail where a later one succeeds. Consider, for example:

  (.*)abc\1
If the subject is "xyz123abc123" the match point is the fourth character. For this reason, such a pattern is not implicitly anchored.

When a capturing subpattern is repeated, the value captured is the substring that matched the final iteration. For example, after

  (tweedle[dume]{3}\s*)+
has matched "tweedledum tweedledee" the value of the captured substring is "tweedledee". However, if there are nested capturing subpatterns, the corresponding captured values may have been set in previous iterations. For example, after
  /(a|(b))+/
matches "aba" the value of the second captured substring is "b".


ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS

With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") repetition, failure of what follows normally causes the repeated item to be re-evaluated to see if a different number of repeats allows the rest of the pattern to match. Sometimes it is useful to prevent this, either to change the nature of the match, or to cause it fail earlier than it otherwise might, when the author of the pattern knows there is no point in carrying on.

Consider, for example, the pattern \d+foo when applied to the subject line

  123456bar
After matching all 6 digits and then failing to match "foo", the normal action of the matcher is to try again with only 5 digits matching the \d+ item, and then with 4, and so on, before ultimately failing. "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides the means for specifying that once a subpattern has matched, it is not to be re-evaluated in this way.

If we use atomic grouping for the previous example, the matcher gives up immediately on failing to match "foo" the first time. The notation is a kind of special parenthesis, starting with (?> as in this example:

  (?>\d+)foo
This kind of parenthesis "locks up" the part of the pattern it contains once it has matched, and a failure further into the pattern is prevented from backtracking into it. Backtracking past it to previous items, however, works as normal.

An alternative description is that a subpattern of this type matches the string of characters that an identical standalone pattern would match, if anchored at the current point in the subject string.

Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as the above example can be thought of as a maximizing repeat that must swallow everything it can. So, while both \d+ and \d+? are prepared to adjust the number of digits they match in order to make the rest of the pattern match, (?>\d+) can only match an entire sequence of digits.

Atomic groups in general can of course contain arbitrarily complicated subpatterns, and can be nested. However, when the subpattern for an atomic group is just a single repeated item, as in the example above, a simpler notation, called a "possessive quantifier" can be used. This consists of an additional + character following a quantifier. Using this notation, the previous example can be rewritten as

  \d++foo
Note that a possessive quantifier can be used with an entire group, for example:
  (abc|xyz){2,3}+
Possessive quantifiers are always greedy; the setting of the PCRE_UNGREEDY option is ignored. They are a convenient notation for the simpler forms of atomic group. However, there is no difference in the meaning of a possessive quantifier and the equivalent atomic group, though there may be a performance difference; possessive quantifiers should be slightly faster.

The possessive quantifier syntax is an extension to the Perl 5.8 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. It ultimately found its way into Perl at release 5.10.

PCRE has an optimization that automatically "possessifies" certain simple pattern constructs. For example, the sequence A+B is treated as A++B because there is no point in backtracking into a sequence of A's when B must follow.

When a pattern contains an unlimited repeat inside a subpattern that can itself be repeated an unlimited number of times, the use of an atomic group is the only way to avoid some failing matches taking a very long time indeed. The pattern

  (\D+|<\d+>)*[!?]
matches an unlimited number of substrings that either consist of non-digits, or digits enclosed in <>, followed by either ! or ?. When it matches, it runs quickly. However, if it is applied to
  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
it takes a long time before reporting failure. This is because the string can be divided between the internal \D+ repeat and the external * repeat in a large number of ways, and all have to be tried. (The example uses [!?] rather than a single character at the end, because both PCRE and Perl have an optimization that allows for fast failure when a single character is used. They remember the last single character that is required for a match, and fail early if it is not present in the string.) If the pattern is changed so that it uses an atomic group, like this:
  ((?>\D+)|<\d+>)*[!?]
sequences of non-digits cannot be broken, and failure happens quickly.


BACK REFERENCES

Outside a character class, a backslash followed by a digit greater than 0 (and possibly further digits) is a back reference to a capturing subpattern earlier (that is, to its left) in the pattern, provided there have been that many previous capturing left parentheses.

However, if the decimal number following the backslash is less than 10, 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 pattern. In other words, the parentheses that are referenced need not be 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 iteration.

It is not possible to have a numerical "forward back reference" to a subpattern whose number is 10 or more using this syntax because a sequence such as \50 is interpreted as a character defined in octal. See the subsection entitled "Non-printing characters" above for further details of the handling of digits following a backslash. There is no such problem when named parentheses are used. A back reference to any subpattern is possible using named parentheses (see below).

Another way of avoiding the ambiguity inherent in the use of digits following a backslash is to use the \g escape sequence. This escape must be followed by an unsigned number or a negative number, optionally enclosed in braces. These examples are all identical:

  (ring), \1
  (ring), \g1
  (ring), \g{1}
An unsigned number specifies an absolute reference without the ambiguity that is present in the older syntax. It is also useful when literal digits follow the reference. A negative number is a relative reference. Consider this example:
  (abc(def)ghi)\g{-1}
The sequence \g{-1} is a reference to the most recently started capturing subpattern before \g, that is, is it equivalent to \2 in this example. Similarly, \g{-2} would be equivalent to \1. The use of relative references can be helpful in long patterns, and also in patterns that are created by joining together fragments that contain references within themselves.

A back reference matches whatever actually matched the capturing subpattern 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 example,
  ((?i)rah)\s+\1
matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original capturing subpattern is matched caselessly.

There are several different ways of writing back references to named subpatterns. The .NET syntax \k{name} and the Perl syntax \k<name> or \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified back reference syntax, in which \g can be used for both numeric and named references, is also supported. We could rewrite the above example in any of the following ways:

  (?<p1>(?i)rah)\s+\k<p1>
  (?'p1'(?i)rah)\s+\k{p1}
  (?P<p1>(?i)rah)\s+(?P=p1)
  (?<p1>(?i)rah)\s+\g{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 references to it always fail by default. For example, the pattern

  (a|(bc))\2
always fails if it starts to match "a" rather than "bc". However, if the PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back reference to an unset value matches an empty string.

Because there may be many capturing parentheses in a pattern, all digits following a backslash are taken as part of a potential back reference number. If the pattern continues with a digit character, some delimiter must be used to terminate the back reference. If the PCRE_EXTENDED option is set, this can be white space. Otherwise, the \g{ syntax or an empty comment (see "Comments" below) can be used.


Recursive back references

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. However, such references can be useful inside repeated subpatterns. For example, the pattern

  (a|b\1)+
matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of the subpattern, the back reference matches the character string corresponding to the previous iteration. In order for this to work, the pattern must be such that the first iteration does not need to match the back reference. This can be done using alternation, as in the example above, or by a quantifier with a minimum of zero.

Back references of this type cause the group that they reference to be treated as an atomic group. Once the whole group has been matched, a subsequent matching failure cannot cause backtracking into the middle of the group.


ASSERTIONS

An assertion is a test on the characters following or preceding the current matching point that does not actually consume any characters. The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are described above.

More complicated assertions are coded as subpatterns. There are two kinds: those that look ahead of the current position in the subject string, and those that look behind it. An assertion subpattern is matched in the normal way, except that it does not cause the current matching position to be changed.

Assertion subpatterns are not capturing subpatterns. If such an assertion contains capturing subpatterns within it, these are counted for the purposes of numbering the capturing subpatterns in the whole pattern. However, substring capturing is carried out only for positive assertions, because it does not make sense for negative assertions.

For compatibility with Perl, assertion subpatterns may be repeated; though it makes no sense to assert the same thing several times, the side effect of capturing parentheses may occasionally be useful. In practice, there only three cases:

(1) If the quantifier is {0}, the assertion is never obeyed during matching. However, it may contain internal capturing parenthesized groups that are called from elsewhere via the subroutine mechanism.

(2) If quantifier is {0,n} where n is greater than zero, it is treated as if it were {0,1}. At run time, the rest of the pattern match is tried with and without the assertion, the order depending on the greediness of the quantifier.

(3) If the minimum repetition is greater than zero, the quantifier is ignored. The assertion is obeyed just once when encountered during matching.


Lookahead assertions

Lookahead assertions start with (?= for positive assertions and (?! for negative assertions. For example,

  \w+(?=;)
matches a word followed by a semicolon, but does not include the semicolon in the match, and
  foo(?!bar)
matches any occurrence of "foo" that is not followed by "bar". Note that the apparently similar pattern
  (?!foo)bar
does not find an occurrence of "bar" that is preceded by something other than "foo"; it finds any occurrence of "bar" whatsoever, because the assertion (?!foo) is always true when the next three characters are "bar". A lookbehind assertion is needed to achieve the other effect.

If you want to force a matching failure at some point in a pattern, the most convenient way to do it is with (?!) because an empty string always matches, so an assertion that requires there not to be an empty string must always fail. The backtracking control verb (*FAIL) or (*F) is a synonym for (?!).


Lookbehind assertions

Lookbehind assertions start with (?<= for positive assertions and (?<! for negative assertions. For example,

  (?<!foo)bar
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 several top-level alternatives, they do not all have to have the same fixed length. Thus
  (?<=bullock|donkey)
is permitted, but
  (?<!dogs?|cats?)
causes an error at compile time. Branches that match different length strings are permitted only at the top level of a lookbehind assertion. This is an extension compared with Perl, which requires all branches to match the same length of string. An assertion such as
  (?<=ab(c|de))
is not permitted, because its single top-level branch can match two different lengths, but it is acceptable to PCRE if rewritten to use two top-level branches:
  (?<=abc|abde)
In some cases, the escape sequence \K (see above) can be used instead of a lookbehind assertion to get round the fixed-length restriction.

The implementation of lookbehind assertions is, for each alternative, to temporarily move the current position back by the fixed length and then try to match. If there are insufficient characters before the current position, the assertion fails.

In a UTF mode, PCRE does not allow the \C escape (which matches a single data unit even in a UTF mode) to appear in lookbehind assertions, because it makes it impossible to calculate the length of the lookbehind. The \X and \R escapes, which can match different numbers of data units, are also not permitted.

"Subroutine" calls (see below) such as (?2) or (?&X) are permitted in lookbehinds, as long as the subpattern matches a fixed-length string. Recursion, however, is not supported.

Possessive quantifiers can be used in conjunction with lookbehind assertions to specify efficient matching of fixed-length strings at the end of subject strings. Consider a simple pattern such as

  abcd$
when applied to a long string that does not match. Because matching proceeds from left to right, PCRE will look for each "a" in the subject and then see if what follows matches the rest of the pattern. If the pattern is specified as
  ^.*abcd$
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)
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.


Using multiple assertions

Several assertions (of any sort) may occur in succession. For example,

  (?<=\d{3})(?<!999)foo
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, 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 of which are not "999". For example, it doesn't match "123abcfoo". A pattern to do that is
  (?<=\d{3}...)(?<!999)foo
This time the first assertion looks at the preceding six characters, checking that the first three are digits, and then the second assertion checks that the preceding three characters are not "999".

Assertions can be nested in any combination. For example,

  (?<=(?<!foo)bar)baz
matches an occurrence of "baz" that is preceded by "bar" which in turn is not preceded by "foo", while
  (?<=\d{3}(?!999)...)foo
is another pattern that matches "foo" preceded by three digits and any three characters that are not "999".


CONDITIONAL SUBPATTERNS

It is possible to cause the matching process to obey a subpattern conditionally or to choose between two alternative subpatterns, depending on the result of an assertion, or whether a specific capturing subpattern has already been matched. The two possible forms of conditional subpattern are:

  (?(condition)yes-pattern)
  (?(condition)yes-pattern|no-pattern)
If the condition is satisfied, the yes-pattern is used; otherwise the no-pattern (if present) is used. If there are more than two alternatives in the subpattern, a compile-time error occurs. Each of the two alternatives may itself contain nested subpatterns of any form, including conditional subpatterns; the restriction to two alternatives applies only at the level of the condition. This pattern fragment is an example where the alternatives are complex:
  (?(1) (A|B|C) | (D | (?(2)E|F) | E) )

There are four kinds of condition: references to subpatterns, references to recursion, a pseudo-condition called DEFINE, and assertions.


Checking for a used subpattern by number

If the text between the parentheses consists of a sequence of digits, the condition is true if a capturing subpattern of that number has previously matched. If there is more than one capturing subpattern with the same number (see the earlier section about duplicate subpattern numbers), the condition is true if any of them have matched. An alternative notation is to precede the digits with a plus or minus sign. In this case, the subpattern number is relative rather than absolute. The most recently opened parentheses can be referenced by (?(-1), the next most recent by (?(-2), and so on. Inside loops it can also make sense to refer to subsequent groups. The next parentheses to be opened can be referenced as (?(+1), and so on. (The value zero in any of these forms is not used; it provokes a compile-time error.)

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) \) )
The first part matches an optional opening parenthesis, and if that character is present, sets it as the first captured substring. The second part matches one or more characters that are not parentheses. The third part is a conditional subpattern that tests whether or not the first set of parentheses matched. If they did, that is, if subject started with an opening parenthesis, the condition is true, and so the yes-pattern 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.

If you were embedding this pattern in a larger one, you could use a relative reference:

  ...other stuff... ( \( )?    [^()]+    (?(-1) \) ) ...
This makes the fragment independent of the parentheses in the larger pattern.


Checking for a used subpattern by name

Perl uses the syntax (?(<name>)...) or (?('name')...) to test for a used subpattern by name. For compatibility with earlier versions of PCRE, which had this facility before Perl, the syntax (?(name)...) is also recognized. However, there is a possible ambiguity with this syntax, because subpattern names may consist entirely of digits. PCRE looks first for a named subpattern; if it cannot find one and the name consists entirely of digits, PCRE looks for a subpattern of that number, which must be greater than zero. Using subpattern names that consist entirely of digits is not recommended.

Rewriting the above example to use a named subpattern gives this:

  (?<OPEN> \( )?    [^()]+    (?(<OPEN>) \) )
If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them has matched.


Checking for pattern recursion

If the condition is the string (R), and there is no subpattern with the name R, the condition is true if a recursive call to the whole pattern or any subpattern has been made. If digits or a name preceded by ampersand follow the letter R, for example:

  (?(R3)...) or (?(R&name)...)
the condition is true if the most recent recursion is into a subpattern whose number or name is given. This condition does not check the entire recursion stack. If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them is the most recent recursion.

At "top level", all these recursion test conditions are false. The syntax for recursive patterns is described below.


Defining subpatterns for use by reference only

If the condition is the string (DEFINE), and there is no subpattern with the name DEFINE, the condition is always false. In this case, there may be only one alternative in the subpattern. It is always skipped if control reaches this point in the pattern; the idea of DEFINE is that it can be used to define subroutines that can be referenced from elsewhere. (The use of subroutines is described below.) For example, a pattern to match an IPv4 address such as "192.168.23.245" could be written like this (ignore white space and line breaks):

  (?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
  \b (?&byte) (\.(?&byte)){3} \b
The first part of the pattern is a DEFINE group inside which a another group named "byte" is defined. This matches an individual component of an IPv4 address (a number less than 256). When matching takes place, this part of the pattern is skipped because DEFINE acts like a false condition. The rest of the pattern uses references to the named group to match the four dot-separated components of an IPv4 address, insisting on a word boundary at each end.


Assertion conditions

If the condition is not in any of the above formats, it must be an assertion. This may be a positive or negative lookahead or lookbehind assertion. Consider this pattern, again containing non-significant white space, and with the two alternatives on the second line:

  (?(?=[^a-z]*[a-z])
  \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
The condition is a positive lookahead assertion that matches an optional sequence of non-letters followed by a letter. In other words, it tests for the presence of at least one letter in the subject. If a letter is found, the subject is matched against the first alternative; otherwise it is matched against the second. This pattern matches strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.


COMMENTS

There are two ways of including comments in patterns that are processed by PCRE. In both cases, the start of the comment must not be in a character class, nor in the middle of any other sequence of related characters such as (?: or a subpattern name or number. The characters that make up a comment play no part in the pattern matching.

The sequence (?# marks the start of a comment that continues up to the next closing parenthesis. Nested parentheses are not permitted. If the PCRE_EXTENDED option is set, an unescaped # character also introduces a comment, which in this case continues to immediately after the next newline character or character sequence in the pattern. Which characters are interpreted as newlines is controlled by the options passed to a compiling function or by a special sequence at the start of the pattern, as described in the section entitled "Newline conventions" above. Note that the end of this type of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. For example, consider this pattern when PCRE_EXTENDED is set, and the default newline convention is in force:

  abc #comment \n still comment
On encountering the # character, pcre_compile() skips along, looking for a newline in the pattern. The sequence \n is still literal at this stage, so it does not terminate the comment. Only an actual character with the code value 0x0a (the default newline) does so.


RECURSIVE PATTERNS

Consider the problem of matching a string in parentheses, allowing for unlimited nested parentheses. Without the use of recursion, the best that can be done is to use a pattern that matches up to some fixed depth of nesting. It is not possible to handle an arbitrary nesting depth.

For some time, Perl has provided a facility that allows regular expressions to recurse (amongst other things). It does this by interpolating Perl code in the expression at run time, and the code can refer to the expression itself. A Perl pattern using code interpolation to solve the parentheses problem can be created like this:

  $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;
The (?p{...}) item interpolates Perl code at run time, and in this case refers recursively to the pattern in which it appears.

Obviously, PCRE cannot support the interpolation of Perl code. Instead, it supports special syntax for recursion of the entire pattern, and also for individual subpattern recursion. After its introduction in PCRE and Python, this kind of recursion was subsequently introduced into Perl at release 5.10.

A special item that consists of (? followed by a number greater than zero and a closing parenthesis is a recursive subroutine call of the subpattern of the given number, provided that it occurs inside that subpattern. (If not, it is a non-recursive subroutine call, which is described in the next section.) The special item (?R) or (?0) is a recursive call of the entire regular expression.

This PCRE pattern solves the nested parentheses problem (assume the PCRE_EXTENDED option is set so that white space is ignored):

  \( ( [^()]++ | (?R) )* \)
First it matches an opening parenthesis. Then it matches any number of substrings which can either be a sequence of non-parentheses, or a recursive match of the pattern itself (that is, a correctly parenthesized substring). Finally there is a closing parenthesis. Note the use of a possessive quantifier to avoid backtracking into sequences of non-parentheses.

If this were part of a larger pattern, you would not want to recurse the entire pattern, so instead you could use this:

  ( \( ( [^()]++ | (?1) )* \) )
We have put the pattern into parentheses, and caused the recursion to refer to them instead of the whole pattern.

In a larger pattern, keeping track of parenthesis numbers can be tricky. This is made easier by the use of relative references. Instead of (?1) in the pattern above you can write (?-2) to refer to the second most recently opened parentheses preceding the recursion. In other words, a negative number counts capturing parentheses leftwards from the point at which it is encountered.

It is also possible to refer to subsequently opened parentheses, by writing references such as (?+2). However, these cannot be recursive because the reference is not inside the parentheses that are referenced. They are always non-recursive subroutine calls, as described in the next section.

An alternative approach is to use named parentheses instead. The Perl syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also supported. We could rewrite the above example as follows:

  (?<pn> \( ( [^()]++ | (?&pn) )* \) )
If there is more than one subpattern with the same name, the earliest one is used.

This particular example pattern that we have been looking at contains nested unlimited repeats, and so the use of a possessive quantifier for matching strings of non-parentheses is important when applying the pattern to strings that do not match. For example, when this pattern is applied to

  (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
it yields "no match" quickly. However, if a possessive quantifier is not used, the match runs for a very long time indeed because there are so many different ways the + and * repeats can carve up the subject, and all have to be tested before failure can be reported.

At the end of a match, the values of capturing parentheses are those from the outermost level. If you want to obtain intermediate values, a callout function can be used (see below and the pcrecallout documentation). If the pattern above is matched against

  (ab(cd)ef)
the value for the inner capturing parentheses (numbered 2) is "ef", which is the last value taken on at the top level. If a capturing subpattern is not matched at the top level, its final captured value is unset, even if it was (temporarily) set at a deeper level during the matching process.

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 via pcre_free afterwards. If no memory can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error.

Do not confuse the (?R) item with the condition (R), which tests for recursion. Consider this pattern, which matches text in angle brackets, allowing for arbitrary nesting. Only digits are allowed in nested brackets (that is, when recursing), whereas any characters are permitted at the outer level.

  < (?: (?(R) \d++  | [^<>]*+) | (?R)) * >
In this pattern, (?(R) is the start of a conditional subpattern, with two different alternatives for the recursive and non-recursive cases. The (?R) item is the actual recursive call.


Differences in recursion processing between PCRE and Perl

Recursion processing in PCRE differs from Perl in two important ways. In PCRE (like Python, but unlike Perl), a recursive subpattern 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 there is a subsequent matching failure. This can be illustrated by the following pattern, which purports to match a palindromic string that contains an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"):

  ^(.|(.)(?1)\2)$
The idea is that it either matches a single character, or two identical characters surrounding a sub-palindrome. In Perl, this pattern works; in PCRE it does not if the pattern is longer than three characters. Consider the subject string "abcba":

At the top level, the first character is matched, but as it is not at the end of the string, the first alternative fails; the second alternative is taken and the recursion kicks in. The recursive call to subpattern 1 successfully matches the next character ("b"). (Note that the beginning and end of line tests are not part of the recursion).

Back at the top level, the next character ("c") is compared with what subpattern 2 matched, which was "a". This fails. Because the recursion is treated as an atomic group, there are now no backtracking points, and so the entire match fails. (Perl is able, at this point, to re-enter the recursion and try the second alternative.) However, if the pattern is written with the alternatives in the other order, things are different:

  ^((.)(?1)\2|.)$
This time, the recursing alternative is tried first, and continues to recurse until it runs out of characters, at which point the recursion fails. But this time we do have another alternative to try at the higher level. That is the big difference: in the previous case the remaining alternative is at a deeper recursion level, which PCRE cannot use.

To change the pattern so that it matches all palindromic strings, not just those with an odd number of characters, it is tempting to change the pattern to this:

  ^((.)(?1)\2|.?)$
Again, this works in Perl, but not in PCRE, and for the same reason. When a deeper recursion has matched a single character, it cannot be entered again in order to match an empty string. The solution is to separate the two cases, and write out the odd and even cases as alternatives at the higher level:
  ^(?:((.)(?1)\2|)|((.)(?3)\4|.))
If you want to match typical palindromic phrases, the pattern has to ignore all non-word characters, which can be done like this:
  ^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$
If run with the PCRE_CASELESS option, this pattern matches phrases such as "A man, a plan, a canal: Panama!" and it works well in both PCRE and Perl. Note the use of the possessive quantifier *+ to avoid backtracking into sequences of non-word characters. Without this, PCRE takes a great deal longer (ten times or more) to match typical phrases, and Perl takes so long that you think it has gone into a loop.

WARNING: The palindrome-matching patterns above work only if the subject string does not start with a palindrome that is shorter than the entire string. For example, although "abcba" is correctly matched, if the subject is "ababa", PCRE finds the palindrome "aba" at the start, then fails at top level because the end of the string does not follow. Once again, it cannot jump back into the recursion to try other alternatives, so the entire match fails.

The second way in which PCRE and Perl differ in their recursion processing is in the handling of captured values. In Perl, when a subpattern is called recursively or as a subpattern (see the next section), it has no access to any values that were captured outside the recursion, whereas in PCRE these values can be referenced. Consider this pattern:

  ^(.)(\1|a(?2))
In PCRE, this pattern matches "bab". The first capturing parentheses match "b", then in the second group, when the back reference \1 fails to match "b", the second alternative matches "a" and then recurses. In the recursion, \1 does now match "b" and so the whole match succeeds. In Perl, the pattern fails to match because inside the recursive call \1 cannot access the externally set value.


SUBPATTERNS AS SUBROUTINES

If the syntax for a recursive subpattern call (either by number or by name) is used outside the parentheses to which it refers, it operates like a subroutine in a programming language. The called subpattern may be defined before or after the reference. A numbered reference can be absolute or relative, as in these examples:

  (...(absolute)...)...(?2)...
  (...(relative)...)...(?-1)...
  (...(?+1)...(relative)...
An earlier example pointed out that the pattern
  (sens|respons)e and \1ibility
matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility". If instead the pattern
  (sens|respons)e and (?1)ibility
is used, it does match "sense and responsibility" as well as the other two strings. Another example is given in the discussion of DEFINE above.

All subroutine calls, whether recursive or not, are always treated as atomic groups. That is, once a subroutine 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. Any capturing parentheses that are set during the subroutine call revert to their previous values afterwards.

Processing options such as case-independence are fixed when a subpattern is defined, so if it is used as a subroutine, such options cannot be changed for different calls. For example, consider this pattern:

  (abc)(?i:(?-1))
It matches "abcabc". It does not match "abcABC" because the change of processing option does not affect the called subpattern.


ONIGURUMA SUBROUTINE SYNTAX

For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or a number enclosed either in angle brackets or single quotes, is an alternative syntax for referencing a subpattern as a subroutine, possibly recursively. Here are two of the examples used above, rewritten using this syntax:

  (?<pn> \( ( (?>[^()]+) | \g<pn> )* \) )
  (sens|respons)e and \g'1'ibility
PCRE supports an extension to Oniguruma: if a number is preceded by a plus or a minus sign it is taken as a relative reference. For example:
  (abc)(?i:\g<-1>)
Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not synonymous. The former is a back reference; the latter is a subroutine call.


CALLOUTS

Perl has a feature whereby using the sequence (?{...}) causes arbitrary Perl code to be obeyed in the middle of matching a regular expression. This makes it possible, amongst other things, to extract different substrings that match the same pair of parentheses when there is a repetition.

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 (8-bit library) or pcre16_callout (16-bit library). 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 points:

  (?C1)abc(?C2)def
If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, callouts are automatically installed before each item in the pattern. They are all numbered 255.

During matching, when PCRE reaches a callout point, 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 the matching function. The callout function may cause matching to proceed, to backtrack, or to fail altogether. A complete description of the interface to the callout function is given in the pcrecallout documentation.


BACKTRACKING CONTROL

Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which are described in the Perl documentation as "experimental and subject to change or removal in a future version of Perl". It goes on to say: "Their usage in production code should be noted to avoid problems during upgrades." The same remarks apply to the PCRE features described in this section.

Since these verbs are specifically related to backtracking, most of them can be used only when the pattern is to be matched using one of the traditional matching functions, which use a backtracking algorithm. With the exception of (*FAIL), which behaves like a failing negative assertion, they cause an error if encountered by a DFA matching function.

If any of these verbs are used in an assertion or in a subpattern that is called as a subroutine (whether or not recursively), their effect is confined to that subpattern; it does not extend to the surrounding pattern, with one exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a successful positive assertion is passed back when a match succeeds (compare capturing parentheses in assertions). Note that such subpatterns are processed as anchored at the point where they are tested. Note also that Perl's treatment of subroutines and assertions is different in some cases.

The new verbs make use of what was previously invalid syntax: an opening parenthesis followed by an asterisk. They are generally of the form (*VERB) or (*VERB:NAME). Some may take either form, with differing behaviour, depending on whether or not an argument is present. A name is any sequence of characters that does not include a closing parenthesis. The maximum length of name is 255 in the 8-bit library and 65535 in the 16-bit library. If the name is empty, that is, if the closing parenthesis immediately follows the colon, the effect is as if the colon were not there. Any number of these verbs may occur in a pattern.


Optimizations that affect backtracking verbs

PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it may know the minimum length of matching subject, or that a particular character must be present. When one of these optimizations suppresses the running of a match, any included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_compile() or pcre_exec(), or by starting the pattern with (*NO_START_OPT). There is more discussion of this option in the section entitled "Option bits for pcre_exec()" in the pcreapi documentation.

Experiments with Perl suggest that it too has similar optimizations, sometimes leading to anomalous results.


Verbs that act immediately

The following verbs act as soon as they are encountered. They may not be followed by a name.

   (*ACCEPT)
This verb causes the match to end successfully, skipping the remainder of the pattern. However, when it is inside a subpattern that is called as a subroutine, only that subpattern is ended successfully. Matching then continues at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so far is captured. For example:
  A((?:A|B(*ACCEPT)|C)D)
This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is captured by the outer parentheses.
  (*FAIL) or (*F)
This verb causes a matching failure, forcing backtracking to occur. It is equivalent to (?!) but easier to read. The Perl documentation notes that it is probably useful only when combined with (?{}) or (??{}). Those are, of course, Perl features that are not present in PCRE. The nearest equivalent is the callout feature, as for example in this pattern:
  a+(?C)(*FAIL)
A match with the string "aaaa" always fails, but the callout is taken before each backtrack happens (in this example, 10 times).


Recording which path was taken

There is one verb whose main purpose is to track how a match was arrived at, though it also has a secondary use in conjunction with advancing the match starting point (see (*SKIP) below).

  (*MARK:NAME) or (*:NAME)
A name is always required with this verb. There may be as many instances of (*MARK) as you like in a pattern, and their names do not have to be unique.

When a match succeeds, the name of the last-encountered (*MARK) on the matching path is passed back to the caller as described in the section entitled "Extra data for pcre_exec()" in the pcreapi documentation. Here is an example of pcretest output, where the /K modifier requests the retrieval and outputting of (*MARK) data:

    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
  data> XY
   0: XY
  MK: A
  XZ
   0: XZ
  MK: B
The (*MARK) name is tagged with "MK:" in this output, and in this example it indicates which of the two alternatives matched. This is a more efficient way of obtaining this information than putting each alternative in its own capturing parentheses.

If (*MARK) is encountered in a positive assertion, its name is recorded and passed back if it is the last-encountered. This does not happen for negative assertions.

After a partial match or a failed match, the name of the last encountered (*MARK) in the entire match process is returned. For example:

    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
  data> XP
  No match, mark = B
Note that in this unanchored example the mark is retained from the match attempt that started at the letter "X" in the subject. Subsequent match attempts starting at "P" and then with an empty string do not get as far as the (*MARK) item, but nevertheless do not reset it.

If you are interested in (*MARK) values after failed matches, you should probably set the PCRE_NO_START_OPTIMIZE option (see above) to ensure that the match is always attempted.


Verbs that act after backtracking

The following verbs do nothing when they are encountered. Matching continues with what follows, but if there is no subsequent match, causing a backtrack to the verb, a failure is forced. That is, backtracking cannot pass to the left of the verb. However, when one of these verbs appears inside an atomic group, its effect is confined to that group, because once the group has been matched, there is never any backtracking into it. In this situation, backtracking can "jump back" to the left of the entire atomic group. (Remember also, as stated above, that this localization also applies in subroutine calls and assertions.)

These verbs differ in exactly what kind of failure occurs when backtracking reaches them.

  (*COMMIT)
This verb, which may not be followed by a name, causes the whole match to fail outright if the rest of the pattern does not match. Even if the pattern is unanchored, no further attempts to find a match by advancing the starting point take place. Once (*COMMIT) has been passed, pcre_exec() is committed to finding a match at the current starting point, or not at all. For example:
  a+(*COMMIT)b
This matches "xxaab" but not "aacaab". It can be thought of as a kind of dynamic anchor, or "I've started, so I must finish." The name of the most recently passed (*MARK) in the path is passed back when (*COMMIT) forces a match failure.

Note that (*COMMIT) at the start of a pattern is not the same as an anchor, unless PCRE's start-of-match optimizations are turned off, as shown in this pcretest example:

    re> /(*COMMIT)abc/
  data> xyzabc
   0: abc
  xyzabc\Y
  No match
PCRE knows that any match must start with "a", so the optimization skips along the subject to "a" before running the first match attempt, which succeeds. When the optimization is disabled by the \Y escape in the second subject, the match starts at "x" and so the (*COMMIT) causes it to fail without trying any other starting points.
  (*PRUNE) or (*PRUNE:NAME)
This verb causes the match to fail at the current starting position in the subject if the rest of the pattern does not match. If the pattern is unanchored, the normal "bumpalong" advance to the next starting character then happens. Backtracking can occur as usual to the left of (*PRUNE), before it is reached, or when matching to the right of (*PRUNE), but if there is no match to the right, backtracking cannot cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alternative to an atomic group or possessive quantifier, but there are some uses of (*PRUNE) that cannot be expressed in any other way. The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an anchored pattern (*PRUNE) has the same effect as (*COMMIT).
  (*SKIP)
This verb, when given without a name, is like (*PRUNE), except that if the pattern is unanchored, the "bumpalong" advance is not to the next character, but to the position in the subject where (*SKIP) was encountered. (*SKIP) signifies that whatever text was matched leading up to it cannot be part of a successful match. Consider:
  a+(*SKIP)b
If the subject is "aaaac...", after the first match attempt fails (starting at the first character in the string), the starting point skips on to start the next attempt at "c". Note that a possessive quantifer does not have the same effect as this example; although it would suppress backtracking during the first match attempt, the second attempt would start at the second character instead of skipping on to "c".
  (*SKIP:NAME)
When (*SKIP) has an associated name, its behaviour is modified. If the following pattern fails to match, the previous path through the pattern is searched for the most recent (*MARK) that has the same name. If one is found, the "bumpalong" advance is to the subject position that corresponds to that (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a matching name is found, the (*SKIP) is ignored.
  (*THEN) or (*THEN:NAME)
This verb causes a skip to the next innermost alternative if the rest of the pattern does not match. That is, it cancels pending backtracking, but only within the current alternative. Its name comes from the observation that it can be used for a pattern-based if-then-else block:
  ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ...
If the COND1 pattern matches, FOO is tried (and possibly further items after the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking into COND1. The behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts like (*PRUNE).

Note that a subpattern that does not contain a | character is just a part of the enclosing alternative; it is not a nested alternation with only one alternative. The effect of (*THEN) extends beyond such a subpattern to the enclosing alternative. Consider this pattern, where A, B, etc. are complex pattern fragments that do not contain any | characters at this level:

  A (B(*THEN)C) | D
If A and B are matched, but there is a failure in C, matching does not backtrack into A; instead it moves to the next alternative, that is, D. However, if the subpattern containing (*THEN) is given an alternative, it behaves differently:
  A (B(*THEN)C | (*FAIL)) | D
The effect of (*THEN) is now confined to the inner subpattern. After a failure in C, matching moves to (*FAIL), which causes the whole subpattern to fail because there are no more alternatives to try. In this case, matching does now backtrack into A.

Note also that a conditional subpattern is not considered as having two alternatives, because only one is ever used. In other words, the | character in a conditional subpattern has a different meaning. Ignoring white space, consider:

  ^.*? (?(?=a) a | b(*THEN)c )
If the subject is "ba", this pattern does not match. Because .*? is ungreedy, it initially matches zero characters. The condition (?=a) then fails, the character "b" is matched, but "c" is not. At this point, matching does not backtrack to .*? as might perhaps be expected from the presence of the | character. The conditional subpattern is part of the single alternative that comprises the whole pattern, and so the match fails. (If there was a backtrack into .*?, allowing it to match "b", the match would succeed.)

The verbs just described provide four different "strengths" of control when subsequent matching fails. (*THEN) is the weakest, carrying on the match at the next alternative. (*PRUNE) comes next, failing the match at the current starting position, but allowing an advance to the next character (for an unanchored pattern). (*SKIP) is similar, except that the advance may be more than one character. (*COMMIT) is the strongest, causing the entire match to fail.

If more than one such verb is present in a pattern, the "strongest" one wins. For example, consider this pattern, where A, B, etc. are complex pattern fragments:

  (A(*COMMIT)B(*THEN)C|D)
Once A has matched, PCRE is committed to this match, at the current starting position. If subsequently B matches, but C does not, the normal (*THEN) action of trying the next alternative (that is, D) does not happen because (*COMMIT) overrides.


SEE ALSO

pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3), pcre16(3).


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 17 June 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre-config.html0000644000222100022210000000657611775533017014125 00000000000000 pcre-config specification

pcre-config man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


SYNOPSIS

pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs16] [--libs-cpp] [--libs-posix] [--cflags] [--cflags-posix]


DESCRIPTION

pcre-config returns the configuration of the installed PCRE libraries and the options required to compile a program to use them. Some of the options apply only to the 8-bit or 16-bit libraries, respectively, and are not available if only one of those libraries has been built. If an unavailable option is encountered, the "usage" information is output.


OPTIONS

--prefix Writes the directory prefix used in the PCRE installation for architecture independent files (/usr on many systems, /usr/local on some systems) to the standard output.

--exec-prefix Writes the directory prefix used in the PCRE installation for architecture dependent files (normally the same as --prefix) to the standard output.

--version Writes the version number of the installed PCRE libraries to the standard output.

--libs Writes to the standard output the command line options required to link with the 8-bit PCRE library (-lpcre on many systems).

--libs16 Writes to the standard output the command line options required to link with the 16-bit PCRE library (-lpcre16 on many systems).

--libs-cpp Writes to the standard output the command line options required to link with PCRE's C++ wrapper library (-lpcrecpp -lpcre on many systems).

--libs-posix Writes to the standard output the command line options required to link with PCRE's POSIX API wrapper library (-lpcreposix -lpcre on many systems).

--cflags Writes to the standard output the command line options required to compile files that use PCRE (this may include some -I options, but is blank on many systems).

--cflags-posix Writes to the standard output the command line options required to compile files that use PCRE's POSIX API wrapper library (this may include some -I options, but is blank on many systems).


SEE ALSO

pcre(3)


AUTHOR

This manual page was originally written by Mark Baker for the Debian GNU/Linux system. It has been subsequently revised as a generic PCRE man page.


REVISION

Last updated: 01 January 2012

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_config.html0000644000222100022210000000660211775533017014175 00000000000000 pcre_config specification

pcre_config man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_config(int what, void *where);

int pcre16_config(int what, void *where);


DESCRIPTION

This function makes it possible for a client program to find out which optional features are available in the version of the PCRE library it is using. The arguments are as follows:

  what     A code specifying what information is required
  where    Points to where to put the data
The where argument must point to an integer variable, except for PCRE_CONFIG_MATCH_LIMIT and PCRE_CONFIG_MATCH_LIMIT_RECURSION, when it must point to an unsigned long integer. The available codes are:
  PCRE_CONFIG_JIT           Availability of just-in-time compiler
                              support (1=yes 0=no)
  PCRE_CONFIG_JITTARGET     String containing information about the
                              target architecture for the JIT compiler,
                              or NULL if there is no JIT support
  PCRE_CONFIG_LINK_SIZE     Internal link size: 2, 3, or 4
  PCRE_CONFIG_MATCH_LIMIT   Internal resource limit
  PCRE_CONFIG_MATCH_LIMIT_RECURSION
                            Internal recursion depth limit
  PCRE_CONFIG_NEWLINE       Value of the default newline sequence:
                                13 (0x000d)    for CR
                                10 (0x000a)    for LF
                              3338 (0x0d0a)    for CRLF
                                -2             for ANYCRLF
                                -1             for ANY
  PCRE_CONFIG_BSR           Indicates what \R matches by default:
                                 0             all Unicode line endings
                                 1             CR, LF, or CRLF only
  PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
                            Threshold of return slots, above which
                              malloc() is used by the POSIX API
  PCRE_CONFIG_STACKRECURSE  Recursion implementation (1=stack 0=heap)
  PCRE_CONFIG_UTF16         Availability of UTF-16 support (1=yes
                               0=no); option for pcre16_config()
  PCRE_CONFIG_UTF8          Availability of UTF-8 support (1=yes 0=no);
                              option for pcre_config()
  PCRE_CONFIG_UNICODE_PROPERTIES
                            Availability of Unicode property support
                              (1=yes 0=no)
The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. That error is also given if PCRE_CONFIG_UTF16 is passed to pcre_config() or if PCRE_CONFIG_UTF8 is passed to pcre16_config().

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_version.html0000644000222100022210000000212511775533017014411 00000000000000 pcre_version specification

pcre_version man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

const char *pcre_version(void);

const char *pcre16_version(void);


DESCRIPTION

This function (even in the 16-bit library) returns a zero-terminated, 8-bit character string that gives the version number of the PCRE library and the date of its release.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcreposix.html0000644000222100022210000002755511775533020013737 00000000000000 pcreposix specification

pcreposix man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


SYNOPSIS OF POSIX API

#include <pcreposix.h>

int regcomp(regex_t *preg, const char *pattern, int cflags);

int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);

size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);

void regfree(regex_t *preg);


DESCRIPTION

This set of functions provides a POSIX-style API for the PCRE regular expression 8-bit library. See the pcreapi documentation for a description of PCRE's native API, which contains much additional functionality. There is no POSIX-style wrapper for PCRE's 16-bit library.

The functions described here are just wrapper functions that ultimately call the PCRE native API. Their prototypes are defined in the pcreposix.h header file, and on Unix systems the library itself is called pcreposix.a, so can be accessed by adding -lpcreposix to the command for linking an application that uses them. Because the POSIX functions call the native ones, it is also necessary to add -lpcre.

I have implemented only those POSIX option bits that can be reasonably mapped to PCRE native options. In addition, the option REG_EXTENDED is defined with the value zero. This has no effect, but since programs that are written to the POSIX interface often use it, this makes it easier to slot in PCRE as a replacement library. Other POSIX options are not even defined.

There are also some other options that are not defined by POSIX. These have been added at the request of users who want to make use of certain PCRE-specific features via the POSIX calling interface.

When PCRE is called via these functions, it is only the API that is POSIX-like in style. The syntax and semantics of the regular expressions themselves are still those of Perl, subject to the setting of various PCRE options, as described below. "POSIX-like in style" means that the API approximates to the POSIX definition; it is not fully POSIX-compatible, and in multi-byte encoding domains it is probably even less compatible.

The header for these functions is supplied as pcreposix.h to avoid any potential clash with other POSIX libraries. It can, of course, be renamed or aliased as regex.h, which is the "correct" name. It provides two structure types, regex_t for compiled internal forms, and regmatch_t for returning captured substrings. It also defines some constants whose names start with "REG_"; these are used for setting options and identifying error codes.


COMPILING A PATTERN

The function regcomp() is called to compile a pattern into an internal form. The pattern is a C string terminated by a binary zero, and is passed in the argument pattern. The preg argument is a pointer to a regex_t structure that is used as a base for storing information about the compiled regular expression.

The argument cflags is either zero, or contains one or more of the bits defined by the following macros:

  REG_DOTALL
The PCRE_DOTALL option is set when the regular expression is passed for compilation to the native function. Note that REG_DOTALL is not part of the POSIX standard.
  REG_ICASE
The PCRE_CASELESS option is set when the regular expression is passed for compilation to the native function.
  REG_NEWLINE
The PCRE_MULTILINE option is set when the regular expression is passed for compilation to the native function. Note that this does not mimic the defined POSIX behaviour for REG_NEWLINE (see the following section).
  REG_NOSUB
The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is passed for compilation to the native function. In addition, when a pattern that is compiled with this flag is passed to regexec() for matching, the nmatch and pmatch arguments are ignored, and no captured strings are returned.
  REG_UCP
The PCRE_UCP option is set when the regular expression is passed for compilation to the native function. This causes PCRE to use Unicode properties when matchine \d, \w, etc., instead of just recognizing ASCII values. Note that REG_UTF8 is not part of the POSIX standard.
  REG_UNGREEDY
The PCRE_UNGREEDY option is set when the regular expression is passed for compilation to the native function. Note that REG_UNGREEDY is not part of the POSIX standard.
  REG_UTF8
The PCRE_UTF8 option is set when the regular expression is passed for compilation to the native function. This causes the pattern itself and all data strings used for matching it to be treated as UTF-8 strings. Note that REG_UTF8 is not part of the POSIX standard.

In the absence of these flags, no options are passed to the native function. This means the the regex is compiled with PCRE default semantics. In particular, the way it handles newline characters in the subject string is the Perl way, not the POSIX way. Note that setting PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE. It does not affect the way newlines are matched by . (they are not) or by a negative class such as [^a] (they are).

The yield of regcomp() is zero on success, and non-zero otherwise. The preg structure is filled in on success, and one member of the structure is public: re_nsub contains the number of capturing subpatterns in the regular expression. Various error codes are defined in the header file.

NOTE: If the yield of regcomp() is non-zero, you must not attempt to use the contents of the preg structure. If, for example, you pass it to regexec(), the result is undefined and your program is likely to crash.


MATCHING NEWLINE CHARACTERS

This area is not simple, because POSIX and Perl take different views of things. It is not possible to get PCRE to obey POSIX semantics, but then PCRE was never intended to be a POSIX engine. The following table lists the different possibilities for matching newline characters in PCRE:

                          Default   Change with

  . matches newline          no     PCRE_DOTALL
  newline matches [^a]       yes    not changeable
  $ matches \n at end        yes    PCRE_DOLLARENDONLY
  $ matches \n in middle     no     PCRE_MULTILINE
  ^ matches \n in middle     no     PCRE_MULTILINE
This is the equivalent table for POSIX:
                          Default   Change with

  . matches newline          yes    REG_NEWLINE
  newline matches [^a]       yes    REG_NEWLINE
  $ matches \n at end        no     REG_NEWLINE
  $ matches \n in middle     no     REG_NEWLINE
  ^ matches \n in middle     no     REG_NEWLINE
PCRE's behaviour is the same as Perl's, except that there is no equivalent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is no way to stop newline from matching [^a].

The default POSIX newline handling can be obtained by setting PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE behave exactly as for the REG_NEWLINE action.


MATCHING A PATTERN

The function regexec() is called to match a compiled pattern preg against a given string, which is by default terminated by a zero byte (but see REG_STARTEND below), subject to the options in eflags. These can be:

  REG_NOTBOL
The PCRE_NOTBOL option is set when calling the underlying PCRE matching function.
  REG_NOTEMPTY
The PCRE_NOTEMPTY option is set when calling the underlying PCRE matching function. Note that REG_NOTEMPTY is not part of the POSIX standard. However, setting this option can give more POSIX-like behaviour in some situations.
  REG_NOTEOL
The PCRE_NOTEOL option is set when calling the underlying PCRE matching function.
  REG_STARTEND
The string is considered to start at string + pmatch[0].rm_so and to have a terminating NUL located at string + pmatch[0].rm_eo (there need not actually be a NUL at that location), regardless of the value of nmatch. This is a BSD extension, compatible with but not specified by IEEE Standard 1003.2 (POSIX.2), and should be used with caution in software intended to be portable to other systems. Note that a non-zero rm_so does not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not how it is matched.

If the pattern was compiled with the REG_NOSUB flag, no data about any matched strings is returned. The nmatch and pmatch arguments of regexec() are ignored.

If the value of nmatch is zero, or if the value pmatch is NULL, no data about any matched strings is returned.

Otherwise,the portion of the string that was matched, and also any captured substrings, are returned via the pmatch argument, which points to an array of nmatch structures of type regmatch_t, containing the members rm_so and rm_eo. These contain the offset to the first character of each substring and the offset to the first character after the end of each substring, respectively. The 0th element of the vector relates to the entire portion of string that was matched; subsequent elements relate to the capturing subpatterns of the regular expression. Unused entries in the array have both structure members set to -1.

A successful match yields a zero return; various error codes are defined in the header file, of which REG_NOMATCH is the "expected" failure code.


ERROR MESSAGES

The regerror() function maps a non-zero errorcode from either regcomp() or regexec() to a printable message. If preg is not NULL, the error should have arisen from the use of that structure. A message terminated by a binary zero is placed in errbuf. The length of the message, including the zero, is limited to errbuf_size. The yield of the function is the size of buffer needed to hold the whole message.


MEMORY USAGE

Compiling a regular expression causes memory to be allocated and associated with the preg structure. The function regfree() frees all such memory, after which preg may no longer be used as a compiled expression.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 09 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrebuild.html0000644000222100022210000004371711775533017013700 00000000000000 pcrebuild specification

pcrebuild man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


PCRE BUILD-TIME OPTIONS

This document describes the optional features of PCRE that can be selected when the library is compiled. It assumes use of the configure script, where the optional features are selected or deselected by providing options to configure before running the make command. However, the same options can be selected in both Unix-like and non-Unix-like environments using the GUI facility of cmake-gui if you are using CMake instead of configure to build PCRE.

There is a lot more information about building PCRE in non-Unix-like environments in the file called NON_UNIX_USE, which is part of the PCRE distribution. You should consult this file as well as the README file if you are building in a non-Unix-like environment.

The complete list of options for configure (which includes the standard ones such as the selection of the installation directory) can be obtained by running

  ./configure --help
The following sections include descriptions of options whose names begin with --enable or --disable. These settings specify changes to the defaults for the configure command. Because of the way that configure works, --enable and --disable always come in pairs, so the complementary option always exists as well, but as it specifies the default, it is not described.


BUILDING 8-BIT and 16-BIT LIBRARIES

By default, a library called libpcre is built, containing functions that take string arguments contained in vectors of bytes, either as single-byte characters, or interpreted as UTF-8 strings. You can also build a separate library, called libpcre16, in which strings are contained in vectors of 16-bit data units and interpreted either as single-unit characters or UTF-16 strings, by adding

  --enable-pcre16
to the configure command. If you do not want the 8-bit library, add
  --disable-pcre8
as well. At least one of the two libraries must be built. Note that the C++ and POSIX wrappers are for the 8-bit library only, and that pcregrep is an 8-bit program. None of these are built if you select only the 16-bit library.


BUILDING SHARED AND STATIC LIBRARIES

The PCRE building process uses libtool to build both shared and static Unix libraries by default. You can suppress one of these by adding one of

  --disable-shared
  --disable-static
to the configure command, as required.


C++ SUPPORT

By default, if the 8-bit library is being built, the configure script will search for a C++ compiler and C++ header files. If it finds them, it automatically builds the C++ wrapper library (which supports only 8-bit strings). You can disable this by adding

  --disable-cpp
to the configure command.


UTF-8 and UTF-16 SUPPORT

To build PCRE with support for UTF Unicode character strings, add

  --enable-utf
to the configure command. This setting applies to both libraries, adding support for UTF-8 to the 8-bit library and support for UTF-16 to the 16-bit library. There are no separate options for enabling UTF-8 and UTF-16 independently because that would allow ridiculous settings such as requesting UTF-16 support while building only the 8-bit library. It is not possible to build one library with UTF support and the other without in the same configuration. (For backwards compatibility, --enable-utf8 is a synonym of --enable-utf.)

Of itself, this setting does not make PCRE treat strings as UTF-8 or UTF-16. As well as compiling PCRE with this option, you also have have to set the PCRE_UTF8 or PCRE_UTF16 option when you call one of the pattern compiling functions.

If you set --enable-utf when compiling in an EBCDIC environment, PCRE expects its input to be either ASCII or UTF-8 (depending on the run-time option). It is not possible to support both EBCDIC and UTF-8 codes in the same version of the library. Consequently, --enable-utf and --enable-ebcdic are mutually exclusive.


UNICODE CHARACTER PROPERTY SUPPORT

UTF support allows the libraries to process character codepoints up to 0x10ffff in the strings that they handle. On its own, however, it does not provide any facilities for accessing the properties of such characters. If you want to be able to use the pattern escapes \P, \p, and \X, which refer to Unicode character properties, you must add

  --enable-unicode-properties
to the configure command. This implies UTF support, even if you have not explicitly requested it.

Including Unicode property support adds around 30K of tables to the PCRE library. Only the general category properties such as Lu and Nd are supported. Details are given in the pcrepattern documentation.


JUST-IN-TIME COMPILER SUPPORT

Just-in-time compiler support is included in the build by specifying

  --enable-jit
This support is available only for certain hardware architectures. If this option is set for an unsupported architecture, a compile time error occurs. See the pcrejit documentation for a discussion of JIT usage. When JIT support is enabled, pcregrep automatically makes use of it, unless you add
  --disable-pcregrep-jit
to the "configure" command.


CODE VALUE OF NEWLINE

By default, PCRE interprets the linefeed (LF) character as indicating the end of a line. This is the normal newline character on Unix-like systems. You can compile PCRE to use carriage return (CR) instead, by adding

  --enable-newline-is-cr
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. There is a fourth option, specified by
  --enable-newline-is-anycrlf
which causes PCRE to recognize any of the three sequences CR, LF, or CRLF as indicating a line ending. Finally, a fifth option, specified by
  --enable-newline-is-any
causes PCRE to recognize any Unicode newline sequence.

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.


WHAT \R MATCHES

By default, the sequence \R in a pattern matches any Unicode newline sequence, whatever has been selected as the line ending sequence. If you specify

  --enable-bsr-anycrlf
the default is changed so that \R matches only CR, LF, or CRLF. Whatever is selected when PCRE is built can be overridden when the library functions are called.


POSIX MALLOC USAGE

When the 8-bit library is called through the POSIX interface (see the pcreposix documentation), additional working storage is required for holding the pointers to capturing substrings, because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The default threshold above which the stack is no longer used is 10; it can be changed by adding a setting such as

  --with-posix-malloc-threshold=20
to the configure command.


HANDLING VERY LARGE PATTERNS

Within a compiled pattern, offset values are used to point from one part to another (for example, from an opening parenthesis to an alternation metacharacter). By default, two-byte values are used for these offsets, leading to a maximum size for a compiled pattern of around 64K. This is sufficient to handle all but the most gigantic patterns. Nevertheless, some people do want to process truly enormous patterns, so it is possible to compile PCRE to use three-byte or four-byte offsets by adding a setting such as

  --with-link-size=3
to the configure command. The value given must be 2, 3, or 4. For the 16-bit library, a value of 3 is rounded up to 4. Using longer offsets slows down the operation of PCRE because it has to load additional data when handling them.


AVOIDING EXCESSIVE STACK USAGE

When matching with the pcre_exec() function, PCRE implements backtracking by making recursive calls to an internal function called match(). In environments where the size of the stack is limited, this can severely limit PCRE's operation. (The Unix environment does not usually suffer from this problem, but it may sometimes be necessary to increase the maximum stack size. There is a discussion in the pcrestack documentation.) 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
to the configure command. With this configuration, PCRE will use the pcre_stack_malloc and pcre_stack_free variables to call memory management functions. By default these point to malloc() and free(), but you can replace the pointers so that your own functions are used instead.

Separate functions are provided rather than using pcre_malloc and pcre_free because the usage is very predictable: the block sizes requested are always the same, and the blocks are always freed in reverse order. A calling program might be able to implement optimized functions that perform better than malloc() and free(). PCRE runs noticeably more slowly when built in this way. This option affects only the pcre_exec() function; it is not relevant for pcre_dfa_exec().


LIMITING PCRE RESOURCE USAGE

Internally, PCRE has a function called match(), which it calls repeatedly (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 documentation. 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.


CREATING CHARACTER TABLES AT BUILD TIME

PCRE uses fixed tables for processing characters whose code values are less than 256. By default, PCRE is built with a set of tables that are distributed in the file pcre_chartables.c.dist. These tables are for ASCII codes only. If you add

  --enable-rebuild-chartables
to the configure command, the distributed tables are no longer used. Instead, a program called dftables is compiled and run. This outputs the source for new set of tables, created in the default locale of your C run-time system. (This method of replacing the tables does not work if you are cross compiling, because dftables is run on the local host. If you need to create alternative tables when cross compiling, you will have to do so "by hand".)


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). This is the case for most computer operating systems. PCRE can, however, be compiled to run in an EBCDIC environment by adding

  --enable-ebcdic
to the configure command. This setting implies --enable-rebuild-chartables. You should only use it if you know that you are in an EBCDIC environment (for example, an IBM mainframe operating system). The --enable-ebcdic option is incompatible with --enable-utf.


PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT

By default, pcregrep reads all files as plain text. You can build it so that it recognizes files whose names end in .gz or .bz2, and reads them with libz or libbz2, respectively, by adding one or both of

  --enable-pcregrep-libz
  --enable-pcregrep-libbz2
to the configure command. These options naturally require that the relevant libraries are installed on your system. Configuration will fail if they are not.


PCREGREP BUFFER SIZE

pcregrep uses an internal buffer to hold a "window" on the file it is scanning, in order to be able to output "before" and "after" lines when it finds a match. The size of the buffer is controlled by a parameter whose default value is 20K. The buffer itself is three times this size, but because of the way it is used for holding "before" lines, the longest line that is guaranteed to be processable is the parameter size. You can change the default parameter value by adding, for example,

  --with-pcregrep-bufsize=50K
to the configure command. The caller of \fPpcregrep\fP can, however, override this value by specifying a run-time option.


PCRETEST OPTION FOR LIBREADLINE SUPPORT

If you add

  --enable-pcretest-libreadline
to the configure command, pcretest is linked with the libreadline library, and when its input is from a terminal, it reads it using the readline() function. This provides line-editing and history facilities. Note that libreadline is GPL-licensed, so if you distribute a binary of pcretest linked in this way, there may be licensing issues.

Setting this option causes the -lreadline option to be added to the pcretest build. In many operating environments with a sytem-installed libreadline this is sufficient. However, in some environments (e.g. if an unmodified distribution version of readline is in use), some extra configuration may be necessary. The INSTALL file for libreadline says this:

  "Readline uses the termcap functions, but does not link with the
  termcap or curses library itself, allowing applications which link
  with readline the to choose an appropriate library."
If your environment has not been set up so that an appropriate library is automatically included, you may need to add something like
  LIBS="-ncurses"
immediately before the configure command.


SEE ALSO

pcreapi(3), pcre16, pcre_config(3).


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 07 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_exec.html0000644000222100022210000001056211775533017013654 00000000000000 pcre_exec specification

pcre_exec man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize);

int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, PCRE_SPTR16 subject, int length, int startoffset, int options, int *ovector, int ovecsize);


DESCRIPTION

This function matches a compiled regular expression against a given subject string, using a matching algorithm that is similar to Perl's. It returns offsets to captured substrings. Its arguments are:

  code         Points to the compiled pattern
  extra        Points to an associated pcre[16]_extra structure,
                 or is NULL
  subject      Points to the subject string
  length       Length of the subject string, in bytes
  startoffset  Offset in bytes in the subject at which to
                 start matching
  options      Option bits
  ovector      Points to a vector of ints for result offsets
  ovecsize     Number of elements in the vector (a multiple of 3)
The options are:
  PCRE_ANCHORED          Match only at the first position
  PCRE_BSR_ANYCRLF       \R matches only CR, LF, or CRLF
  PCRE_BSR_UNICODE       \R matches all Unicode line endings
  PCRE_NEWLINE_ANY       Recognize any Unicode newline sequence
  PCRE_NEWLINE_ANYCRLF   Recognize CR, LF, & CRLF as newline sequences
  PCRE_NEWLINE_CR        Recognize CR as the only newline sequence
  PCRE_NEWLINE_CRLF      Recognize CRLF as the only newline sequence
  PCRE_NEWLINE_LF        Recognize LF as the only newline sequence
  PCRE_NOTBOL            Subject string is not the beginning of a line
  PCRE_NOTEOL            Subject string is not the end of a line
  PCRE_NOTEMPTY          An empty string is not a valid match
  PCRE_NOTEMPTY_ATSTART  An empty string at the start of the subject
                           is not a valid match
  PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
  PCRE_NO_UTF16_CHECK    Do not check the subject for UTF-16
                           validity (only relevant if PCRE_UTF16
                           was set at compile time)
  PCRE_NO_UTF8_CHECK     Do not check the subject for UTF-8
                           validity (only relevant if PCRE_UTF8
                           was set at compile time)
  PCRE_PARTIAL           ) Return PCRE_ERROR_PARTIAL for a partial
  PCRE_PARTIAL_SOFT      )   match if no full matches are found
  PCRE_PARTIAL_HARD      Return PCRE_ERROR_PARTIAL for a partial match
                           if that is found before a full match
For details of partial matching, see the pcrepartial page. A pcre_extra structure contains the following fields:
  flags            Bits indicating which fields are set
  study_data       Opaque data from pcre[16]_study()
  match_limit      Limit on internal resource use
  match_limit_recursion  Limit on internal recursion depth
  callout_data     Opaque data passed back to callouts
  tables           Points to character tables or is NULL
  mark             For passing back a *MARK pointer
  executable_jit   Opaque data from JIT compilation
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrematching.html0000644000222100022210000002411711775533020014356 00000000000000 pcrematching specification

pcrematching man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


PCRE MATCHING ALGORITHMS

This document describes the two different algorithms that are available in PCRE for matching a compiled regular expression against a given subject string. The "standard" algorithm is the one provided by the pcre_exec() and pcre16_exec() functions. These work in the same was as Perl's matching function, and provide a Perl-compatible matching operation. The just-in-time (JIT) optimization that is described in the pcrejit documentation is compatible with these functions.

An alternative algorithm is provided by the pcre_dfa_exec() and pcre16_dfa_exec() functions; they operate in a different way, and are not Perl-compatible. This alternative has advantages and disadvantages compared with the standard algorithm, and these are described below.

When there is only one possible way in which a given subject string can match a pattern, the two algorithms give the same answer. A difference arises, however, when there are multiple possibilities. For example, if the pattern

  ^<.*>
is matched against the string
  <something> <something else> <something further>
there are three possible answers. The standard algorithm finds only one of them, whereas the alternative algorithm finds all three.


REGULAR EXPRESSIONS AS TREES

The set of strings that are matched by a regular expression can be represented 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 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

In the terminology of Jeffrey Friedl's book "Mastering Regular Expressions", the standard algorithm is an "NFA algorithm". It conducts a depth-first search of the pattern tree. That is, it proceeds along a single path through the tree, checking that the subject matches what is required. When there is a mismatch, the algorithm tries any alternatives at the current point, and if they all fail, it backs up to the previous branch point in the tree, and tries the next alternative branch at that level. This often involves backing up (moving to the left) in the subject string as well. The order in which repetition branches are tried is controlled by the greedy or ungreedy nature of the quantifier.

If a leaf node is reached, a matching string has been found, and at that point the algorithm stops. Thus, if there is more than one possible match, this algorithm returns the first one that it finds. Whether this is the shortest, the longest, or some intermediate length depends on the way the greedy and ungreedy repetition quantifiers are specified in the pattern.

Because it ends up with a single path through the tree, it is relatively straightforward for this algorithm to keep track of the substrings that are matched by portions of the pattern in parentheses. This provides support for capturing parentheses and back references.


THE ALTERNATIVE MATCHING ALGORITHM

This algorithm conducts a breadth-first search of the tree. Starting from the first matching point in the subject, it scans the subject string from left to right, once, character by character, and as it does this, it remembers all the paths through the tree that represent valid matches. In Friedl's terminology, this is a kind of "DFA algorithm", though it is not implemented as a traditional finite state machine (it keeps multiple states active simultaneously).

Although the general principle of this matching algorithm is that it scans the subject string only once, without backtracking, there is one exception: when a lookaround assertion is encountered, the characters following or preceding the current point have to be independently inspected.

The scan continues until either the end of the subject is reached, or there are no more unterminated paths. At this point, terminated paths represent the different matching possibilities (if there are none, the match has failed). Thus, if there is more than one possible match, this algorithm finds all of them, and in particular, it finds the longest. The matches are returned in decreasing order of length. There is an option to stop the algorithm after the first match (which is necessarily the shortest) is found.

Note that all the matches that are found start at the same point in the subject. If the pattern

  cat(er(pillar)?)?
is matched against the string "the caterpillar catchment", the result will be the three strings "caterpillar", "cater", and "cat" that start at the fifth character of the subject. The algorithm does not automatically move on to find matches that start at later positions.

There are a number of features of PCRE regular expressions that are not supported by the alternative matching algorithm. They are as follows:

1. Because the algorithm finds all possible matches, the greedy or ungreedy nature of repetition quantifiers is not relevant. Greedy and ungreedy quantifiers are treated in exactly the same way. However, possessive quantifiers can make a difference when what follows could also match what is quantified, for example in a pattern like this:

  ^a++\w!
This pattern matches "aaab!" but not "aaa!", which would be matched by a non-possessive quantifier. Similarly, if an atomic group is present, it is matched as if it were a standalone pattern at the current point, and the longest match is then "locked in" for the rest of the overall pattern.

2. When dealing with multiple paths through the tree simultaneously, it is not straightforward to keep track of captured substrings for the different matching possibilities, and PCRE's implementation of this algorithm does not attempt to do this. This means that no captured substrings are available.

3. Because no substrings are captured, back references within the pattern are not supported, and cause errors if encountered.

4. For the same reason, conditional expressions that use a backreference as the condition or test for a specific group recursion are not supported.

5. Because many paths through the tree may be active, the \K escape sequence, which resets the start of the match when encountered (but may be on some paths and not on others), is not supported. It causes an error if encountered.

6. Callouts are supported, but the value of the capture_top field is always 1, and the value of the capture_last field is always -1.

7. The \C escape sequence, which (in the standard algorithm) always matches a single data unit, even in UTF-8 or UTF-16 modes, is not supported in these modes, because the alternative algorithm moves through the subject string one character (not data unit) at a time, for all active paths through the tree.

8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) are not supported. (*FAIL) is supported, and behaves like a failing negative assertion.


ADVANTAGES OF THE ALTERNATIVE ALGORITHM

Using the alternative matching algorithm provides the following advantages:

1. All possible matches (at a single point in the subject) are automatically found, and in particular, the longest match is found. To find more than one match using the standard algorithm, you have to do kludgy things with callouts.

2. Because the alternative algorithm scans the subject string just once, and never needs to backtrack (except for lookbehinds), it is possible to pass very long subject strings to the matching function in several pieces, checking for partial matching each time. Although it is possible to do multi-segment matching using the standard algorithm by retaining partially matched substrings, it is more complicated. The pcrepartial documentation gives details of partial matching and discusses multi-segment matching.


DISADVANTAGES OF THE ALTERNATIVE ALGORITHM

The alternative algorithm suffers from a number of disadvantages:

1. It is substantially slower than the standard algorithm. This is partly because it has to search for all possible matches, but is also because it is less susceptible to optimization.

2. Capturing parentheses and back references are not supported.

3. Although atomic groups are supported, their use does not provide the performance advantage that it does for the standard algorithm.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 08 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_get_substring.html0000644000222100022210000000373611775533017015614 00000000000000 pcre_get_substring specification

pcre_get_substring man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr);

int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_SPTR16 *stringptr);


DESCRIPTION

This is a convenience function for extracting a captured substring. The arguments are:

  subject       Subject that has been successfully matched
  ovector       Offset vector that pcre[16]_exec() used
  stringcount   Value returned by pcre[16]_exec()
  stringnumber  Number of the required substring
  stringptr     Where to put the string pointer
The memory in which the substring is placed is obtained by calling pcre[16]_malloc(). The convenience function pcre[16]_free_substring() can be used to free it when it is no longer needed. The yield of the function is the length of the substring, PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string number is invalid.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcresample.html0000644000222100022210000000731011775533020014041 00000000000000 pcresample specification

pcresample man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

PCRE SAMPLE PROGRAM

A simple, complete demonstration program, to get you started with using PCRE, is supplied in the file pcredemo.c in the PCRE distribution. A listing of this program is given in the pcredemo documentation. If you do not have a copy of the PCRE distribution, you can save this listing to re-create pcredemo.c.

The demonstration program, which uses the original PCRE 8-bit library, compiles the regular expression that is its first argument, and matches it against the subject string in its second argument. No PCRE options are set, and default character tables are used. If matching succeeds, the program outputs the portion of the subject that matched, together with the contents of any captured substrings.

If the -g option is given on the command line, the program then goes on to check for further matches of the same regular expression in the same subject string. The logic is a little bit tricky because of the possibility of matching an empty string. Comments in the code explain what is going on.

If PCRE is installed in the standard include and library directories for your operating system, you should be able to compile the demonstration program using this command:

  gcc -o pcredemo pcredemo.c -lpcre
If PCRE is installed elsewhere, you may need to add additional options to the command line. For example, on a Unix-like system that has PCRE installed in /usr/local, you can compile the demonstration program using a command like this:
  gcc -o pcredemo -I/usr/local/include pcredemo.c -L/usr/local/lib -lpcre
In a Windows environment, if you want to statically link the program against a non-dll pcre.a file, you must uncomment the line that defines PCRE_STATIC before including pcre.h, because otherwise the pcre_malloc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results.

Once you have compiled and linked the demonstration program, you can run simple tests like this:

  ./pcredemo 'cat|dog' 'the cat sat on the mat'
  ./pcredemo -g 'cat|dog' 'the dog sat on the cat'
Note that there is a much more comprehensive test program, called pcretest, which supports many more facilities for testing regular expressions and both PCRE libraries. The pcredemo program is provided as a simple coding example.

If you try to run pcredemo when PCRE is not installed in the standard library directory, you may get an error like this on some operating systems (e.g. Solaris):

  ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or directory
This is caused by the way shared library support works on those systems. You need to add
  -R/usr/local/lib
(for example) to the compile command to get round this problem.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 10 January 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_free_substring_list.html0000644000222100022210000000226611775533017017006 00000000000000 pcre_free_substring_list specification

pcre_free_substring_list man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

void pcre_free_substring_list(const char **stringptr);

void pcre16_free_substring_list(PCRE_SPTR16 *stringptr);


DESCRIPTION

This is a convenience function for freeing the store obtained by a previous call to pcre[16]_get_substring_list(). Its only argument is a pointer to the list of string pointers.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcregrep.html0000644000222100022210000010222311775533017013522 00000000000000 pcregrep specification

pcregrep man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.


SYNOPSIS

pcregrep [options] [long options] [pattern] [path1 path2 ...]


DESCRIPTION

pcregrep searches files for character patterns, in the same way as other grep commands do, but it uses the PCRE regular expression library to support patterns that are compatible with the regular expressions of Perl 5. See pcrepattern(3) for a full description of syntax and semantics of the regular expressions that PCRE supports.

Patterns, whether supplied on the command line or in a separate file, are given without delimiters. For example:

  pcregrep Thursday /etc/motd
If you attempt to use delimiters (for example, by surrounding a pattern with slashes, as is common in Perl scripts), they are interpreted as part of the pattern. Quotes can of course be used to delimit patterns on the command line because they are interpreted by the shell, and indeed they are required if a pattern contains white space or shell metacharacters.

The first argument that follows any option settings is treated as the single pattern to be matched when neither -e nor -f is present. Conversely, when one or both of these options are used to specify patterns, all arguments are treated as path names. At least one of -e, -f, or an argument pattern must be provided.

If no files are specified, pcregrep reads the standard input. The standard input can also be referenced by a name consisting of a single hyphen. For example:

  pcregrep some-pattern /file1 - /file3
By default, each line that matches a pattern is copied to the standard output, and if there is more than one file, the file name is output at the start of each line, followed by a colon. However, there are options that can change how pcregrep behaves. In particular, the -M option makes it possible to search for patterns that span line boundaries. What defines a line boundary is controlled by the -N (--newline) option.

The amount of memory used for buffering files that are being scanned is controlled by a parameter that can be set by the --buffer-size option. The default value for this parameter is specified when pcregrep is built, with the default default being 20K. A block of memory three times this size is used (to allow for buffering "before" and "after" lines). An error occurs if a line overflows the buffer.

Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater. BUFSIZ is defined in <stdio.h>. When there is more than one pattern (specified by the use of -e and/or -f), each pattern is applied to each line in the order in which they are defined, except that all the -e patterns are tried before the -f patterns.

By default, as soon as one pattern matches (or fails to match when -v is used), no further patterns are considered. However, if --colour (or --color) is used to colour the matching substrings, or if --only-matching, --file-offsets, or --line-offsets is used to output only the part of the line that matched (either shown literally, or as an offset), scanning resumes immediately following the match, so that further matches on the same line can be found. If there are multiple patterns, they are all tried on the remainder of the line, but patterns that follow the one that matched are not tried on the earlier part of the line.

This is the same behaviour as GNU grep, but it does mean that the order in which multiple patterns are specified can affect the output when one of the above options is used.

Patterns that can match an empty string are accepted, but empty string matches are never recognized. An example is the pattern "(super)?(man)?", in which all components are optional. This pattern finds all occurrences of both "super" and "man"; the output differs from matching with "super|man" when only the matching substrings are being shown.

If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses the value to set a locale when calling the PCRE library. The --locale option can be used to override this.


SUPPORT FOR COMPRESSED FILES

It is possible to compile pcregrep so that it uses libz or libbz2 to read files whose names end in .gz or .bz2, respectively. You can find out whether your binary has support for one or both of these file types by running it with the --help option. If the appropriate support is not present, files are treated as plain text. The standard input is always so treated.


BINARY FILES

By default, a file that contains a binary zero byte within the first 1024 bytes is identified as a binary file, and is processed specially. (GNU grep also identifies binary files in this manner.) See the --binary-files option for a means of changing the way binary files are handled.


OPTIONS

The order in which some of the options appear can affect the output. For example, both the -h and -l options affect the printing of file names. Whichever comes later in the command line will be the one that takes effect. Numerical values for options may be followed by K or M, to signify multiplication by 1024 or 1024*1024 respectively.

-- This terminates the list of options. It is useful if the next item on the command line starts with a hyphen but is not an option. This allows for the processing of patterns and filenames that start with hyphens.

-A number, --after-context=number Output number lines of context after each matching line. If filenames and/or line numbers are being output, a hyphen separator is used instead of a colon for the context lines. A line containing "--" is output between each group of lines, unless they are in fact contiguous in the input file. The value of number is expected to be relatively small. However, pcregrep guarantees to have up to 8K of following text available for context output.

-a, --text Treat binary files as text. This is equivalent to --binary-files=text.

-B number, --before-context=number Output number lines of context before each matching line. If filenames and/or line numbers are being output, a hyphen separator is used instead of a colon for the context lines. A line containing "--" is output between each group of lines, unless they are in fact contiguous in the input file. The value of number is expected to be relatively small. However, pcregrep guarantees to have up to 8K of preceding text available for context output.

--binary-files=word Specify how binary files are to be processed. If the word is "binary" (the default), pattern matching is performed on binary files, but the only output is "Binary file <name> matches" when a match succeeds. If the word is "text", which is equivalent to the -a or --text option, binary files are processed in the same way as any other file. In this case, when a match succeeds, the output may be binary garbage, which can have nasty effects if sent to a terminal. If the word is "without-match", which is equivalent to the -I option, binary files are not processed at all; they are assumed not to be of interest.

--buffer-size=number Set the parameter that controls how much memory is used for buffering files that are being scanned.

-C number, --context=number Output number lines of context both before and after each matching line. This is equivalent to setting both -A and -B to the same value.

-c, --count Do not output individual lines from the files that are being scanned; instead output the number of lines that would otherwise have been shown. If no lines are selected, the number zero is output. If several files are are being scanned, a count is output for each of them. However, if the --files-with-matches option is also used, only those files whose counts are greater than zero are listed. When -c is used, the -A, -B, and -C options are ignored.

--colour, --color If this option is given without any data, it is equivalent to "--colour=auto". If data is required, it must be given in the same shell item, separated by an equals sign.

--colour=value, --color=value This option specifies under what circumstances the parts of a line that matched a pattern should be coloured in the output. By default, the output is not coloured. The value (which is optional, see above) may be "never", "always", or "auto". In the latter case, colouring happens only if the standard output is connected to a terminal. More resources are used when colouring is enabled, because pcregrep has to search for all possible matches in a line, not just one, in order to colour them all.

The colour that is used can be specified by setting the environment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value of this variable should be a string of two numbers, separated by a semicolon. They are copied directly into the control string for setting colour on a terminal, so it is your responsibility to ensure that they make sense. If neither of the environment variables is set, the default is "1;31", which gives red.

-D action, --devices=action If an input path is not a regular file or a directory, "action" specifies how it is to be processed. Valid values are "read" (the default) or "skip" (silently skip the path).

-d action, --directories=action If an input path is a directory, "action" specifies how it is to be processed. Valid values are "read" (the default), "recurse" (equivalent to the -r option), or "skip" (silently skip the path). In the default case, directories are read as if they were ordinary files. In some operating systems the effect of reading a directory like this is an immediate end-of-file.

-e pattern, --regex=pattern, --regexp=pattern Specify a pattern to be matched. This option can be used multiple times in order to specify several patterns. It can also be used as a way of specifying a single pattern that starts with a hyphen. When -e is used, no argument pattern is taken from the command line; all arguments are treated as file names. There is an overall maximum of 100 patterns. They are applied to each line in the order in which they are defined until one matches (or fails to match if -v is used). If -f is used with -e, the command line patterns are matched first, followed by the patterns from the file, independent of the order in which these options are specified. Note that multiple use of -e is not the same as a single pattern with alternatives. For example, X|Y finds the first character in a line that is X or Y, whereas if the two patterns are given separately, pcregrep finds X if it is present, even if it follows Y in the line. It finds Y only if there is no X in the line. This really matters only if you are using -o to show the part(s) of the line that matched.

--exclude=pattern When pcregrep is searching the files in a directory as a consequence of the -r (recursive search) option, any regular files whose names match the pattern are excluded. Subdirectories are not excluded by this option; they are searched recursively, subject to the --exclude-dir and --include_dir options. The pattern is a PCRE regular expression, and is matched against the final component of the file name (not the entire path). If a file name matches both --include and --exclude, it is excluded. There is no short form for this option.

--exclude-dir=pattern When pcregrep is searching the contents of a directory as a consequence of the -r (recursive search) option, any subdirectories whose names match the pattern are excluded. (Note that the \fP--exclude\fP option does not affect subdirectories.) The pattern is a PCRE regular expression, and is matched against the final component of the name (not the entire path). If a subdirectory name matches both --include-dir and --exclude-dir, it is excluded. There is no short form for this option.

-F, --fixed-strings Interpret each pattern as a list of fixed strings, separated by newlines, instead of as a regular expression. The -w (match as a word) and -x (match whole line) options can be used with -F. They apply to each of the fixed strings. A line is selected if any of the fixed strings are found in it (subject to -w or -x, if present).

-f filename, --file=filename Read a number of patterns from the file, one per line, and match them against each line of input. A data line is output if any of the patterns match it. The filename can be given as "-" to refer to the standard input. When -f is used, patterns specified on the command line using -e may also be present; they are tested before the file's patterns. However, no other pattern is taken from the command line; all arguments are treated as the names of paths to be searched. There is an overall maximum of 100 patterns. Trailing white space is removed from each line, and blank lines are ignored. An empty file contains no patterns and therefore matches nothing. See also the comments about multiple patterns versus a single pattern with alternatives in the description of -e above.

--file-list=filename Read a list of files to be searched from the given file, one per line. Trailing white space is removed from each line, and blank lines are ignored. These files are searched before any others that may be listed on the command line. The filename can be given as "-" to refer to the standard input. If --file and --file-list are both specified as "-", patterns are read first. This is useful only when the standard input is a terminal, from which further lines (the list of files) can be read after an end-of-file indication.

--file-offsets Instead of showing lines or parts of lines that match, show each match as an offset from the start of the file and a length, separated by a comma. In this mode, no context is shown. That is, the -A, -B, and -C options are ignored. If there is more than one match in a line, each of them is shown separately. This option is mutually exclusive with --line-offsets and --only-matching.

-H, --with-filename Force the inclusion of the filename at the start of output lines when searching a single file. By default, the filename is not shown in this case. For matching lines, the filename is followed by a colon; for context lines, a hyphen separator is used. If a line number is also being output, it follows the file name.

-h, --no-filename Suppress the output filenames when searching multiple files. By default, filenames are shown when multiple files are searched. For matching lines, the filename is followed by a colon; for context lines, a hyphen separator is used. If a line number is also being output, it follows the file name.

--help Output a help message, giving brief details of the command options and file type support, and then exit.

-I Treat binary files as never matching. This is equivalent to --binary-files=without-match.

-i, --ignore-case Ignore upper/lower case distinctions during comparisons.

--include=pattern When pcregrep is searching the files in a directory as a consequence of the -r (recursive search) option, only those regular files whose names match the pattern are included. Subdirectories are always included and searched recursively, subject to the \fP--include-dir\fP and --exclude-dir options. The pattern is a PCRE regular expression, and is matched against the final component of the file name (not the entire path). If a file name matches both --include and --exclude, it is excluded. There is no short form for this option.

--include-dir=pattern When pcregrep is searching the contents of a directory as a consequence of the -r (recursive search) option, only those subdirectories whose names match the pattern are included. (Note that the --include option does not affect subdirectories.) The pattern is a PCRE regular expression, and is matched against the final component of the name (not the entire path). If a subdirectory name matches both --include-dir and --exclude-dir, it is excluded. There is no short form for this option.

-L, --files-without-match Instead of outputting lines from the files, just output the names of the files that do not contain any lines that would have been output. Each file name is output once, on a separate line.

-l, --files-with-matches Instead of outputting lines from the files, just output the names of the files containing lines that would have been output. Each file name is output once, on a separate line. Searching normally stops as soon as a matching line is found in a file. However, if the -c (count) option is also used, matching continues in order to obtain the correct count, and those files that have at least one match are listed along with their counts. Using this option with -c is a way of suppressing the listing of files with no matches.

--label=name This option supplies a name to be used for the standard input when file names are being output. If not supplied, "(standard input)" is used. There is no short form for this option.

--line-buffered When this option is given, input is read and processed line by line, and the output is flushed after each write. By default, input is read in large chunks, unless pcregrep can determine that it is reading from a terminal (which is currently possible only in Unix environments). Output to terminal is normally automatically flushed by the operating system. This option can be useful when the input or output is attached to a pipe and you do not want pcregrep to buffer up large amounts of data. However, its use will affect performance, and the -M (multiline) option ceases to work.

--line-offsets Instead of showing lines or parts of lines that match, show each match as a line number, the offset from the start of the line, and a length. The line number is terminated by a colon (as usual; see the -n option), and the offset and length are separated by a comma. In this mode, no context is shown. That is, the -A, -B, and -C options are ignored. If there is more than one match in a line, each of them is shown separately. This option is mutually exclusive with --file-offsets and --only-matching.

--locale=locale-name This option specifies a locale to be used for pattern matching. It overrides the value in the LC_ALL or LC_CTYPE environment variables. If no locale is specified, the PCRE library's default (usually the "C" locale) is used. There is no short form for this option.

--match-limit=number Processing some regular expression patterns can require a very large amount of memory, leading in some cases to a program crash if not enough is available. Other patterns may take a very long time to search for all possible matching strings. The pcre_exec() function that is called by pcregrep to do the matching has two parameters that can limit the resources that it uses.

The --match-limit option provides a means of limiting resource usage when processing patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats. Internally, PCRE uses a function called match() which it calls repeatedly (sometimes recursively). The limit set by --match-limit is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place.

The --recursion-limit option is similar to --match-limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursive calls, which in turn limits the amount of memory that can be used. The recursion depth is a smaller number than the total number of calls, because not all calls to match() are recursive. This limit is of use only if it is set smaller than --match-limit.

There are no short forms for these options. The default settings are specified when the PCRE library is compiled, with the default default being 10 million.

-M, --multiline Allow patterns to match more than one line. When this option is given, patterns may usefully contain literal newline characters and internal occurrences of ^ and $ characters. The output for a successful match may consist of more than one line, the last of which is the one in which the match ended. If the matched string ends with a newline sequence the output ends at the end of that line.

When this option is set, the PCRE library is called in "multiline" mode. There is a limit to the number of lines that can be matched, imposed by the way that pcregrep buffers the input file as it scans it. However, pcregrep ensures that at least 8K characters or the rest of the document (whichever is the shorter) are available for forward matching, and similarly the previous 8K characters (or all the previous characters, if fewer than 8K) are guaranteed to be available for lookbehind assertions. This option does not work when input is read line by line (see \fP--line-buffered\fP.)

-N newline-type, --newline=newline-type The PCRE library supports five different conventions for indicating the ends of lines. They are the single-character sequences CR (carriage return) and LF (linefeed), the two-character sequence CRLF, an "anycrlf" convention, which recognizes any of the preceding three types, and an "any" convention, in which any Unicode line ending sequence is assumed to end a line. The Unicode sequences are the three just mentioned, plus VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029).

When the PCRE library is built, a default line-ending sequence is specified. This is normally the standard sequence for the operating system. Unless otherwise specified by this option, pcregrep uses the library's default. The possible values for this option are CR, LF, CRLF, ANYCRLF, or ANY. This makes it possible to use pcregrep on files that have come from other environments without having to modify their line endings. If the data that is being scanned does not agree with the convention set by this option, pcregrep may behave in strange ways.

-n, --line-number Precede each output line by its line number in the file, followed by a colon for matching lines or a hyphen for context lines. If the filename is also being output, it precedes the line number. This option is forced if --line-offsets is used.

--no-jit If the PCRE library is built with support for just-in-time compiling (which speeds up matching), pcregrep automatically makes use of this, unless it was explicitly disabled at build time. This option can be used to disable the use of JIT at run time. It is provided for testing and working round problems. It should never be needed in normal use.

-o, --only-matching Show only the part of the line that matched a pattern instead of the whole line. In this mode, no context is shown. That is, the -A, -B, and -C options are ignored. If there is more than one match in a line, each of them is shown separately. If -o is combined with -v (invert the sense of the match to find non-matching lines), no output is generated, but the return code is set appropriately. If the matched portion of the line is empty, nothing is output unless the file name or line number are being printed, in which case they are shown on an otherwise empty line. This option is mutually exclusive with --file-offsets and --line-offsets.

-onumber, --only-matching=number Show only the part of the line that matched the capturing parentheses of the given number. Up to 32 capturing parentheses are supported. Because these options can be given without an argument (see above), if an argument is present, it must be given in the same shell item, for example, -o3 or --only-matching=2. The comments given for the non-argument case above also apply to this case. If the specified capturing parentheses do not exist in the pattern, or were not set in the match, nothing is output unless the file name or line number are being printed.

-q, --quiet Work quietly, that is, display nothing except error messages. The exit status indicates whether or not any matches were found.

-r, --recursive If any given path is a directory, recursively scan the files it contains, taking note of any --include and --exclude settings. By default, a directory is read as a normal file; in some operating systems this gives an immediate end-of-file. This option is a shorthand for setting the -d option to "recurse".

--recursion-limit=number See --match-limit above.

-s, --no-messages Suppress error messages about non-existent or unreadable files. Such files are quietly skipped. However, the return code is still 2, even if matches were found in other files.

-u, --utf-8 Operate in UTF-8 mode. This option is available only if PCRE has been compiled with UTF-8 support. Both patterns and subject lines must be valid strings of UTF-8 characters.

-V, --version Write the version numbers of pcregrep and the PCRE library that is being used to the standard error stream.

-v, --invert-match Invert the sense of the match, so that lines which do not match any of the patterns are the ones that are found.

-w, --word-regex, --word-regexp Force the patterns to match only whole words. This is equivalent to having \b at the start and end of the pattern.

-x, --line-regex, --line-regexp Force the patterns to be anchored (each must start matching at the beginning of a line) and in addition, require them to match entire lines. This is equivalent to having ^ and $ characters at the start and end of each alternative branch in every pattern.


ENVIRONMENT VARIABLES

The environment variables LC_ALL and LC_CTYPE are examined, in that order, for a locale. The first one that is set is used. This can be overridden by the --locale option. If no locale is set, the PCRE library's default (usually the "C" locale) is used.


NEWLINES

The -N (--newline) option allows pcregrep to scan files with different newline conventions from the default. However, the setting of this option does not affect the way in which pcregrep writes information to the standard error and output streams. It uses the string "\n" in C printf() calls to indicate newlines, relying on the C I/O library to convert this to an appropriate sequence if the output is sent to a file.


OPTIONS COMPATIBILITY

Many of the short and long forms of pcregrep's options are the same as in the GNU grep program. Any long option of the form --xxx-regexp (GNU terminology) is also available as --xxx-regex (PCRE terminology). However, the --file-list, --file-offsets, --include-dir, --line-offsets, --locale, --match-limit, -M, --multiline, -N, --newline, --recursion-limit, -u, and --utf-8 options are specific to pcregrep, as is the use of the --only-matching option with a capturing parentheses number.

Although most of the common options work the same way, a few are different in pcregrep. For example, the --include option's argument is a glob for GNU grep, but a regular expression for pcregrep. If both the -c and -l options are given, GNU grep lists only file names, without counts, but pcregrep gives the counts.


OPTIONS WITH DATA

There are four different ways in which an option with data can be specified. If a short form option is used, the data may follow immediately, or (with one exception) in the next command line item. For example:

  -f/some/file
  -f /some/file
The exception is the -o option, which may appear with or without data. Because of this, if data is present, it must follow immediately in the same item, for example -o3.

If a long form option is used, the data may appear in the same command line item, separated by an equals character, or (with two exceptions) it may appear in the next command line item. For example:

  --file=/some/file
  --file /some/file
Note, however, that if you want to supply a file name beginning with ~ as data in a shell command, and have the shell expand ~ to a home directory, you must separate the file name from the option, because the shell does not treat ~ specially unless it is at the start of an item.

The exceptions to the above are the --colour (or --color) and --only-matching options, for which the data is optional. If one of these options does have data, it must be given in the first form, using an equals character. Otherwise pcregrep will assume that it has no data.


MATCHING ERRORS

It is possible to supply a regular expression that takes a very long time to fail to match certain lines. Such patterns normally involve nested indefinite repeats, for example: (a+)*\d when matched against a line of a's with no final digit. The PCRE matching function has a resource limit that causes it to abort in these circumstances. If this happens, pcregrep outputs an error message and the line that caused the problem to the standard error stream. If there are more than 20 such errors, pcregrep gives up.

The --match-limit option of pcregrep can be used to set the overall resource limit; there is a second option called --recursion-limit that sets a limit on the amount of memory (usually stack) that is used (see the discussion of these options above).


DIAGNOSTICS

Exit status is 0 if any matches were found, 1 if no matches were found, and 2 for syntax errors, overlong lines, non-existent or inaccessible files (even if matches were found in other files) or too many matching errors. Using the -s option to suppress error messages about inaccessible files does not affect the return code.


SEE ALSO

pcrepattern(3), pcretest(1).


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 04 March 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcrelimits.html0000644000222100022210000000536411775533020014070 00000000000000 pcrelimits specification

pcrelimits man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SIZE AND OTHER LIMITATIONS

There are some size limitations in PCRE but it is hoped that they will never in practice be relevant.

The maximum length of a compiled pattern is approximately 64K data units (bytes for the 8-bit library, 16-bit units for the 16-bit library) if PCRE is compiled with the default internal linkage size of 2 bytes. If you want to process regular expressions that are truly enormous, you can compile PCRE with an internal linkage size of 3 or 4 (when building the 16-bit library, 3 is rounded up to 4). See the README file in the source distribution and the pcrebuild documentation for details. In these cases the limit is substantially larger. However, the speed of execution is slower.

All values in repeating quantifiers must be less than 65536.

There is no limit to the number of parenthesized subpatterns, but there can be no more than 65535 capturing subpatterns.

There is a limit to the number of forward references to subsequent subpatterns of around 200,000. Repeated forward references with fixed upper limits, for example, (?2){0,100} when subpattern number 2 is to the right, are included in the count. There is no limit to the number of backward references.

The maximum length of name for a named subpattern is 32 characters, and the maximum number of named subpatterns is 10000.

The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit library.

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 indefinite 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.


AUTHOR

Philip Hazel
University Computing Service
Cambridge CB2 3QH, England.


REVISION

Last updated: 04 May 2012
Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_copy_named_substring.html0000644000222100022210000000400511775533017017141 00000000000000 pcre_copy_named_substring specification

pcre_copy_named_substring man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int buffersize);

int pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_UCHAR16 *buffer, int buffersize);


DESCRIPTION

This is a convenience function for extracting a captured substring, identified by name, into a given buffer. The arguments are:

  code          Pattern that was successfully matched
  subject       Subject that has been successfully matched
  ovector       Offset vector that pcre[16]_exec() used
  stringcount   Value returned by pcre[16]_exec()
  stringname    Name of the required substring
  buffer        Buffer to receive the string
  buffersize    Size of buffer
The yield is the length of the substring, PCRE_ERROR_NOMEMORY if the buffer was too small, or PCRE_ERROR_NOSUBSTRING if the string name is invalid.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_compile.html0000644000222100022210000000777511775533017014374 00000000000000 pcre_compile specification

pcre_compile man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr);

pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr);


DESCRIPTION

This function compiles a regular expression into an internal form. It is the same as pcre[16]_compile2(), except for the absence of the errorcodeptr argument. Its arguments are:

  pattern       A zero-terminated string containing the
                  regular expression to be compiled
  options       Zero or more option bits
  errptr        Where to put an error message
  erroffset     Offset in pattern where error was found
  tableptr      Pointer to character tables, or NULL to
                  use the built-in default
The option bits are:
  PCRE_ANCHORED           Force pattern anchoring
  PCRE_AUTO_CALLOUT       Compile automatic callouts
  PCRE_BSR_ANYCRLF        \R matches only CR, LF, or CRLF
  PCRE_BSR_UNICODE        \R matches all Unicode line endings
  PCRE_CASELESS           Do caseless matching
  PCRE_DOLLAR_ENDONLY     $ not to match newline at end
  PCRE_DOTALL             . matches anything including NL
  PCRE_DUPNAMES           Allow duplicate names for subpatterns
  PCRE_EXTENDED           Ignore white space and # comments
  PCRE_EXTRA              PCRE extra features
                            (not much use currently)
  PCRE_FIRSTLINE          Force matching to be before newline
  PCRE_JAVASCRIPT_COMPAT  JavaScript compatibility
  PCRE_MULTILINE          ^ and $ match newlines within data
  PCRE_NEWLINE_ANY        Recognize any Unicode newline sequence
  PCRE_NEWLINE_ANYCRLF    Recognize CR, LF, and CRLF as newline
                            sequences
  PCRE_NEWLINE_CR         Set CR as the newline sequence
  PCRE_NEWLINE_CRLF       Set CRLF as the newline sequence
  PCRE_NEWLINE_LF         Set LF as the newline sequence
  PCRE_NO_AUTO_CAPTURE    Disable numbered capturing paren-
                            theses (named ones available)
  PCRE_NO_UTF16_CHECK     Do not check the pattern for UTF-16
                            validity (only relevant if
                            PCRE_UTF16 is set)
  PCRE_NO_UTF8_CHECK      Do not check the pattern for UTF-8
                            validity (only relevant if
                            PCRE_UTF8 is set)
  PCRE_UCP                Use Unicode properties for \d, \w, etc.
  PCRE_UNGREEDY           Invert greediness of quantifiers
  PCRE_UTF16              Run in pcre16_compile() UTF-16 mode
  PCRE_UTF8               Run in pcre_compile() UTF-8 mode
PCRE must be built with UTF support in order to use PCRE_UTF8/16 and PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.

The yield of the function is a pointer to a private data structure that contains the compiled pattern, or NULL if an error was detected. Note that compiling regular expressions with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/html/pcre_dfa_exec.html0000644000222100022210000001226511775533017014470 00000000000000 pcre_dfa_exec specification

pcre_dfa_exec man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

SYNOPSIS

#include <pcre.h>

int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize, int *workspace, int wscount);

int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, PCRE_SPTR16 subject, int length, int startoffset, int options, int *ovector, int ovecsize, int *workspace, int wscount);


DESCRIPTION

This function matches a compiled regular expression against a given subject string, using an alternative matching algorithm that scans the subject string just once (not Perl-compatible). Note that the main, Perl-compatible, matching function is pcre[16]_exec(). The arguments for this function are:

  code         Points to the compiled pattern
  extra        Points to an associated pcre[16]_extra structure,
                 or is NULL
  subject      Points to the subject string
  length       Length of the subject string, in bytes
  startoffset  Offset in bytes in the subject at which to
                 start matching
  options      Option bits
  ovector      Points to a vector of ints for result offsets
  ovecsize     Number of elements in the vector
  workspace    Points to a vector of ints used as working space
  wscount      Number of elements in the vector
The options are:
  PCRE_ANCHORED          Match only at the first position
  PCRE_BSR_ANYCRLF       \R matches only CR, LF, or CRLF
  PCRE_BSR_UNICODE       \R matches all Unicode line endings
  PCRE_NEWLINE_ANY       Recognize any Unicode newline sequence
  PCRE_NEWLINE_ANYCRLF   Recognize CR, LF, & CRLF as newline sequences
  PCRE_NEWLINE_CR        Recognize CR as the only newline sequence
  PCRE_NEWLINE_CRLF      Recognize CRLF as the only newline sequence
  PCRE_NEWLINE_LF        Recognize LF as the only newline sequence
  PCRE_NOTBOL            Subject is not the beginning of a line
  PCRE_NOTEOL            Subject is not the end of a line
  PCRE_NOTEMPTY          An empty string is not a valid match
  PCRE_NOTEMPTY_ATSTART  An empty string at the start of the subject
                           is not a valid match
  PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
  PCRE_NO_UTF16_CHECK    Do not check the subject for UTF-16
                           validity (only relevant if PCRE_UTF16
                           was set at compile time)
  PCRE_NO_UTF8_CHECK     Do not check the subject for UTF-8
                           validity (only relevant if PCRE_UTF8
                           was set at compile time)
  PCRE_PARTIAL           ) Return PCRE_ERROR_PARTIAL for a partial
  PCRE_PARTIAL_SOFT      )   match if no full matches are found
  PCRE_PARTIAL_HARD      Return PCRE_ERROR_PARTIAL for a partial match
                           even if there is a full match as well
  PCRE_DFA_SHORTEST      Return only the shortest match
  PCRE_DFA_RESTART       Restart after a partial match
There are restrictions on what may appear in a pattern when using this matching function. Details are given in the pcrematching documentation. For details of partial matching, see the pcrepartial page.

A pcre[16]_extra structure contains the following fields:

  flags            Bits indicating which fields are set
  study_data       Opaque data from pcre[16]_study()
  match_limit      Limit on internal resource use
  match_limit_recursion  Limit on internal recursion depth
  callout_data     Opaque data passed back to callouts
  tables           Points to character tables or is NULL
  mark             For passing back a *MARK pointer
  executable_jit   Opaque data from JIT compilation
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. For this matching function, the match_limit and match_limit_recursion fields are not used, and must not be set. The PCRE_EXTRA_EXECUTABLE_JIT flag and the corresponding variable are ignored.

There is a complete description of the PCRE native API in the pcreapi page and a description of the POSIX API in the pcreposix page.

Return to the PCRE index page.

pcre-8.31/doc/pcre_maketables.30000644000222100022210000000145611735631562013274 00000000000000.TH PCRE_MAKETABLES 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B const unsigned char *pcre_maketables(void); .PP .B const unsigned char *pcre16_maketables(void); . .SH DESCRIPTION .rs .sp This function builds a set of character tables for character values less than 256. These can be passed to \fBpcre[16]_compile()\fP to override PCRE's internal, built-in tables (which were made by \fBpcre[16]_maketables()\fP when PCRE was compiled). You might want to do this if you are using a non-standard locale. The function yields a pointer to the tables. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/index.html.src0000644000222100022210000001573011742321001012630 00000000000000 PCRE specification

Perl-compatible Regular Expressions (PCRE)

The HTML documentation for PCRE comprises the following pages:

pcre   Introductory page
pcre16   Discussion of the 16-bit PCRE library
pcre-config   Information about the installation configuration
pcreapi   PCRE's native API
pcrebuild   Options for building PCRE
pcrecallout   The callout facility
pcrecompat   Compability with Perl
pcrecpp   The C++ wrapper for the PCRE library
pcredemo   A demonstration C program that uses the PCRE library
pcregrep   The pcregrep command
pcrejit   Discussion of the just-in-time optimization support
pcrelimits   Details of size and other limits
pcrematching   Discussion of the two matching algorithms
pcrepartial   Using PCRE for partial matching
pcrepattern   Specification of the regular expressions supported by PCRE
pcreperform   Some comments on performance
pcreposix   The POSIX API to the PCRE library
pcreprecompile   How to save and re-use compiled patterns
pcresample   Discussion of the pcredemo program
pcrestack   Discussion of PCRE's stack usage
pcresyntax   Syntax quick-reference summary
pcretest   The pcretest command for testing PCRE
pcreunicode   Discussion of Unicode and UTF-8/UTF-16 support

There are also individual pages that summarize the interface for each function in the library. There is a single page for each pair of 8-bit/16-bit functions.

pcre_assign_jit_stack   Assign stack for JIT matching
pcre_compile   Compile a regular expression
pcre_compile2   Compile a regular expression (alternate interface)
pcre_config   Show build-time configuration options
pcre_copy_named_substring   Extract named substring into given buffer
pcre_copy_substring   Extract numbered substring into given buffer
pcre_dfa_exec   Match a compiled pattern to a subject string (DFA algorithm; not Perl compatible)
pcre_free_study   Free study data
pcre_exec   Match a compiled pattern to a subject string (Perl compatible)
pcre_free_substring   Free extracted substring
pcre_free_substring_list   Free list of extracted substrings
pcre_fullinfo   Extract information about a pattern
pcre_get_named_substring   Extract named substring into new memory
pcre_get_stringnumber   Convert captured string name to number
pcre_get_substring   Extract numbered substring into new memory
pcre_get_substring_list   Extract all substrings into new memory
pcre_info   Obsolete information extraction function
pcre_jit_stack_alloc   Create a stack for JIT matching
pcre_jit_stack_free   Free a JIT matching stack
pcre_maketables   Build character tables in current locale
pcre_pattern_to_host_byte_order   Convert compiled pattern to host byte order if necessary
pcre_refcount   Maintain reference count in compiled pattern
pcre_study   Study a compiled pattern
pcre_utf16_to_host_byte_order   Convert UTF-16 string to host byte order if necessary
pcre_version   Return PCRE version and release date
pcre-8.31/doc/pcre_get_substring_list.30000644000222100022210000000271111735631472015071 00000000000000.TH PCRE_GET_SUBSTRING_LIST 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_get_substring_list(const char *\fIsubject\fP, .ti +5n .B int *\fIovector\fP, int \fIstringcount\fP, "const char ***\fIlistptr\fP);" .PP .B int pcre16_get_substring_list(PCRE_SPTR16 \fIsubject\fP, .ti +5n .B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR16 **\fIlistptr\fP);" . .SH DESCRIPTION .rs .sp This is a convenience function for extracting a list of all the captured substrings. The arguments are: .sp \fIsubject\fP Subject that has been successfully matched \fIovector\fP Offset vector that \fBpcre[16]_exec\fP used \fIstringcount\fP Value returned by \fBpcre[16]_exec\fP \fIlistptr\fP Where to put a pointer to the list .sp The memory in which the substrings and the list are placed is obtained by calling \fBpcre[16]_malloc()\fP. The convenience function \fBpcre[16]_free_substring_list()\fP can be used to free it when it is no longer needed. A pointer to a list of pointers is put in the variable whose address is in \fIlistptr\fP. The list is terminated by a NULL pointer. The yield of the function is zero on success or PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcreposix.30000644000222100022210000002470311735643357012174 00000000000000.TH PCREPOSIX 3 "09 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions. .SH "SYNOPSIS OF POSIX API" .rs .sp .B #include .PP .SM .B int regcomp(regex_t *\fIpreg\fP, const char *\fIpattern\fP, .ti +5n .B int \fIcflags\fP); .PP .B int regexec(regex_t *\fIpreg\fP, const char *\fIstring\fP, .ti +5n .B size_t \fInmatch\fP, regmatch_t \fIpmatch\fP[], int \fIeflags\fP); .PP .B size_t regerror(int \fIerrcode\fP, const regex_t *\fIpreg\fP, .ti +5n .B char *\fIerrbuf\fP, size_t \fIerrbuf_size\fP); .PP .B void regfree(regex_t *\fIpreg\fP); . .SH DESCRIPTION .rs .sp This set of functions provides a POSIX-style API for the PCRE regular expression 8-bit library. See the .\" HREF \fBpcreapi\fP .\" documentation for a description of PCRE's native API, which contains much additional functionality. There is no POSIX-style wrapper for PCRE's 16-bit library. .P The functions described here are just wrapper functions that ultimately call the PCRE native API. Their prototypes are defined in the \fBpcreposix.h\fP header file, and on Unix systems the library itself is called \fBpcreposix.a\fP, so can be accessed by adding \fB-lpcreposix\fP to the command for linking an application that uses them. Because the POSIX functions call the native ones, it is also necessary to add \fB-lpcre\fP. .P I have implemented only those POSIX option bits that can be reasonably mapped to PCRE native options. In addition, the option REG_EXTENDED is defined with the value zero. This has no effect, but since programs that are written to the POSIX interface often use it, this makes it easier to slot in PCRE as a replacement library. Other POSIX options are not even defined. .P There are also some other options that are not defined by POSIX. These have been added at the request of users who want to make use of certain PCRE-specific features via the POSIX calling interface. .P When PCRE is called via these functions, it is only the API that is POSIX-like in style. The syntax and semantics of the regular expressions themselves are still those of Perl, subject to the setting of various PCRE options, as described below. "POSIX-like in style" means that the API approximates to the POSIX definition; it is not fully POSIX-compatible, and in multi-byte encoding domains it is probably even less compatible. .P The header for these functions is supplied as \fBpcreposix.h\fP to avoid any potential clash with other POSIX libraries. It can, of course, be renamed or aliased as \fBregex.h\fP, which is the "correct" name. It provides two structure types, \fIregex_t\fP for compiled internal forms, and \fIregmatch_t\fP for returning captured substrings. It also defines some constants whose names start with "REG_"; these are used for setting options and identifying error codes. . . .SH "COMPILING A PATTERN" .rs .sp The function \fBregcomp()\fP is called to compile a pattern into an internal form. The pattern is a C string terminated by a binary zero, and is passed in the argument \fIpattern\fP. The \fIpreg\fP argument is a pointer to a \fBregex_t\fP structure that is used as a base for storing information about the compiled regular expression. .P The argument \fIcflags\fP is either zero, or contains one or more of the bits defined by the following macros: .sp REG_DOTALL .sp The PCRE_DOTALL option is set when the regular expression is passed for compilation to the native function. Note that REG_DOTALL is not part of the POSIX standard. .sp REG_ICASE .sp The PCRE_CASELESS option is set when the regular expression is passed for compilation to the native function. .sp REG_NEWLINE .sp The PCRE_MULTILINE option is set when the regular expression is passed for compilation to the native function. Note that this does \fInot\fP mimic the defined POSIX behaviour for REG_NEWLINE (see the following section). .sp REG_NOSUB .sp The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is passed for compilation to the native function. In addition, when a pattern that is compiled with this flag is passed to \fBregexec()\fP for matching, the \fInmatch\fP and \fIpmatch\fP arguments are ignored, and no captured strings are returned. .sp REG_UCP .sp The PCRE_UCP option is set when the regular expression is passed for compilation to the native function. This causes PCRE to use Unicode properties when matchine \ed, \ew, etc., instead of just recognizing ASCII values. Note that REG_UTF8 is not part of the POSIX standard. .sp REG_UNGREEDY .sp The PCRE_UNGREEDY option is set when the regular expression is passed for compilation to the native function. Note that REG_UNGREEDY is not part of the POSIX standard. .sp REG_UTF8 .sp The PCRE_UTF8 option is set when the regular expression is passed for compilation to the native function. This causes the pattern itself and all data strings used for matching it to be treated as UTF-8 strings. Note that REG_UTF8 is not part of the POSIX standard. .P In the absence of these flags, no options are passed to the native function. This means the the regex is compiled with PCRE default semantics. In particular, the way it handles newline characters in the subject string is the Perl way, not the POSIX way. Note that setting PCRE_MULTILINE has only \fIsome\fP of the effects specified for REG_NEWLINE. It does not affect the way newlines are matched by . (they are not) or by a negative class such as [^a] (they are). .P The yield of \fBregcomp()\fP is zero on success, and non-zero otherwise. The \fIpreg\fP structure is filled in on success, and one member of the structure is public: \fIre_nsub\fP contains the number of capturing subpatterns in the regular expression. Various error codes are defined in the header file. .P NOTE: If the yield of \fBregcomp()\fP is non-zero, you must not attempt to use the contents of the \fIpreg\fP structure. If, for example, you pass it to \fBregexec()\fP, the result is undefined and your program is likely to crash. . . .SH "MATCHING NEWLINE CHARACTERS" .rs .sp This area is not simple, because POSIX and Perl take different views of things. It is not possible to get PCRE to obey POSIX semantics, but then PCRE was never intended to be a POSIX engine. The following table lists the different possibilities for matching newline characters in PCRE: .sp Default Change with .sp . matches newline no PCRE_DOTALL newline matches [^a] yes not changeable $ matches \en at end yes PCRE_DOLLARENDONLY $ matches \en in middle no PCRE_MULTILINE ^ matches \en in middle no PCRE_MULTILINE .sp This is the equivalent table for POSIX: .sp Default Change with .sp . matches newline yes REG_NEWLINE newline matches [^a] yes REG_NEWLINE $ matches \en at end no REG_NEWLINE $ matches \en in middle no REG_NEWLINE ^ matches \en in middle no REG_NEWLINE .sp PCRE's behaviour is the same as Perl's, except that there is no equivalent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is no way to stop newline from matching [^a]. .P The default POSIX newline handling can be obtained by setting PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE behave exactly as for the REG_NEWLINE action. . . .SH "MATCHING A PATTERN" .rs .sp The function \fBregexec()\fP is called to match a compiled pattern \fIpreg\fP against a given \fIstring\fP, which is by default terminated by a zero byte (but see REG_STARTEND below), subject to the options in \fIeflags\fP. These can be: .sp REG_NOTBOL .sp The PCRE_NOTBOL option is set when calling the underlying PCRE matching function. .sp REG_NOTEMPTY .sp The PCRE_NOTEMPTY option is set when calling the underlying PCRE matching function. Note that REG_NOTEMPTY is not part of the POSIX standard. However, setting this option can give more POSIX-like behaviour in some situations. .sp REG_NOTEOL .sp The PCRE_NOTEOL option is set when calling the underlying PCRE matching function. .sp REG_STARTEND .sp The string is considered to start at \fIstring\fP + \fIpmatch[0].rm_so\fP and to have a terminating NUL located at \fIstring\fP + \fIpmatch[0].rm_eo\fP (there need not actually be a NUL at that location), regardless of the value of \fInmatch\fP. This is a BSD extension, compatible with but not specified by IEEE Standard 1003.2 (POSIX.2), and should be used with caution in software intended to be portable to other systems. Note that a non-zero \fIrm_so\fP does not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not how it is matched. .P If the pattern was compiled with the REG_NOSUB flag, no data about any matched strings is returned. The \fInmatch\fP and \fIpmatch\fP arguments of \fBregexec()\fP are ignored. .P If the value of \fInmatch\fP is zero, or if the value \fIpmatch\fP is NULL, no data about any matched strings is returned. .P Otherwise,the portion of the string that was matched, and also any captured substrings, are returned via the \fIpmatch\fP argument, which points to an array of \fInmatch\fP structures of type \fIregmatch_t\fP, containing the members \fIrm_so\fP and \fIrm_eo\fP. These contain the offset to the first character of each substring and the offset to the first character after the end of each substring, respectively. The 0th element of the vector relates to the entire portion of \fIstring\fP that was matched; subsequent elements relate to the capturing subpatterns of the regular expression. Unused entries in the array have both structure members set to -1. .P A successful match yields a zero return; various error codes are defined in the header file, of which REG_NOMATCH is the "expected" failure code. . . .SH "ERROR MESSAGES" .rs .sp The \fBregerror()\fP function maps a non-zero errorcode from either \fBregcomp()\fP or \fBregexec()\fP to a printable message. If \fIpreg\fP is not NULL, the error should have arisen from the use of that structure. A message terminated by a binary zero is placed in \fIerrbuf\fP. The length of the message, including the zero, is limited to \fIerrbuf_size\fP. The yield of the function is the size of buffer needed to hold the whole message. . . .SH MEMORY USAGE .rs .sp Compiling a regular expression causes memory to be allocated and associated with the \fIpreg\fP structure. The function \fBregfree()\fP frees all such memory, after which \fIpreg\fP may no longer be used as a compiled expression. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 09 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcrebuild.30000644000222100022210000003640411760163326012121 00000000000000.TH PCREBUILD 3 "07 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions . . .SH "PCRE BUILD-TIME OPTIONS" .rs .sp This document describes the optional features of PCRE that can be selected when the library is compiled. It assumes use of the \fBconfigure\fP script, where the optional features are selected or deselected by providing options to \fBconfigure\fP before running the \fBmake\fP command. However, the same options can be selected in both Unix-like and non-Unix-like environments using the GUI facility of \fBcmake-gui\fP if you are using \fBCMake\fP instead of \fBconfigure\fP to build PCRE. .P There is a lot more information about building PCRE in non-Unix-like environments in the file called \fINON_UNIX_USE\fP, which is part of the PCRE distribution. You should consult this file as well as the \fIREADME\fP file if you are building in a non-Unix-like environment. .P The complete list of options for \fBconfigure\fP (which includes the standard ones such as the selection of the installation directory) can be obtained by running .sp ./configure --help .sp The following sections include descriptions of options whose names begin with --enable or --disable. These settings specify changes to the defaults for the \fBconfigure\fP command. Because of the way that \fBconfigure\fP works, --enable and --disable always come in pairs, so the complementary option always exists as well, but as it specifies the default, it is not described. . . .SH "BUILDING 8-BIT and 16-BIT LIBRARIES" .rs .sp By default, a library called \fBlibpcre\fP is built, containing functions that take string arguments contained in vectors of bytes, either as single-byte characters, or interpreted as UTF-8 strings. You can also build a separate library, called \fBlibpcre16\fP, in which strings are contained in vectors of 16-bit data units and interpreted either as single-unit characters or UTF-16 strings, by adding .sp --enable-pcre16 .sp to the \fBconfigure\fP command. If you do not want the 8-bit library, add .sp --disable-pcre8 .sp as well. At least one of the two libraries must be built. Note that the C++ and POSIX wrappers are for the 8-bit library only, and that \fBpcregrep\fP is an 8-bit program. None of these are built if you select only the 16-bit library. . . .SH "BUILDING SHARED AND STATIC LIBRARIES" .rs .sp The PCRE building process uses \fBlibtool\fP to build both shared and static Unix libraries by default. You can suppress one of these by adding one of .sp --disable-shared --disable-static .sp to the \fBconfigure\fP command, as required. . . .SH "C++ SUPPORT" .rs .sp By default, if the 8-bit library is being built, the \fBconfigure\fP script will search for a C++ compiler and C++ header files. If it finds them, it automatically builds the C++ wrapper library (which supports only 8-bit strings). You can disable this by adding .sp --disable-cpp .sp to the \fBconfigure\fP command. . . .SH "UTF-8 and UTF-16 SUPPORT" .rs .sp To build PCRE with support for UTF Unicode character strings, add .sp --enable-utf .sp to the \fBconfigure\fP command. This setting applies to both libraries, adding support for UTF-8 to the 8-bit library and support for UTF-16 to the 16-bit library. There are no separate options for enabling UTF-8 and UTF-16 independently because that would allow ridiculous settings such as requesting UTF-16 support while building only the 8-bit library. It is not possible to build one library with UTF support and the other without in the same configuration. (For backwards compatibility, --enable-utf8 is a synonym of --enable-utf.) .P Of itself, this setting does not make PCRE treat strings as UTF-8 or UTF-16. As well as compiling PCRE with this option, you also have have to set the PCRE_UTF8 or PCRE_UTF16 option when you call one of the pattern compiling functions. .P If you set --enable-utf when compiling in an EBCDIC environment, PCRE expects its input to be either ASCII or UTF-8 (depending on the run-time option). It is not possible to support both EBCDIC and UTF-8 codes in the same version of the library. Consequently, --enable-utf and --enable-ebcdic are mutually exclusive. . . .SH "UNICODE CHARACTER PROPERTY SUPPORT" .rs .sp UTF support allows the libraries to process character codepoints up to 0x10ffff in the strings that they handle. On its own, however, it does not provide any facilities for accessing the properties of such characters. If you want to be able to use the pattern escapes \eP, \ep, and \eX, which refer to Unicode character properties, you must add .sp --enable-unicode-properties .sp to the \fBconfigure\fP command. This implies UTF support, even if you have not explicitly requested it. .P Including Unicode property support adds around 30K of tables to the PCRE library. Only the general category properties such as \fILu\fP and \fINd\fP are supported. Details are given in the .\" HREF \fBpcrepattern\fP .\" documentation. . . .SH "JUST-IN-TIME COMPILER SUPPORT" .rs .sp Just-in-time compiler support is included in the build by specifying .sp --enable-jit .sp This support is available only for certain hardware architectures. If this option is set for an unsupported architecture, a compile time error occurs. See the .\" HREF \fBpcrejit\fP .\" documentation for a discussion of JIT usage. When JIT support is enabled, pcregrep automatically makes use of it, unless you add .sp --disable-pcregrep-jit .sp to the "configure" command. . . .SH "CODE VALUE OF NEWLINE" .rs .sp By default, PCRE interprets the linefeed (LF) character as indicating the end of a line. This is the normal newline character on Unix-like systems. You can compile PCRE to use carriage return (CR) instead, by adding .sp --enable-newline-is-cr .sp to the \fBconfigure\fP command. There is also a --enable-newline-is-lf option, which explicitly specifies linefeed as the newline character. .sp Alternatively, you can specify that line endings are to be indicated by the two character sequence CRLF. If you want this, add .sp --enable-newline-is-crlf .sp to the \fBconfigure\fP command. There is a fourth option, specified by .sp --enable-newline-is-anycrlf .sp which causes PCRE to recognize any of the three sequences CR, LF, or CRLF as indicating a line ending. Finally, a fifth option, specified by .sp --enable-newline-is-any .sp causes PCRE to recognize any Unicode newline sequence. .P 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. . . .SH "WHAT \eR MATCHES" .rs .sp By default, the sequence \eR in a pattern matches any Unicode newline sequence, whatever has been selected as the line ending sequence. If you specify .sp --enable-bsr-anycrlf .sp the default is changed so that \eR matches only CR, LF, or CRLF. Whatever is selected when PCRE is built can be overridden when the library functions are called. . . .SH "POSIX MALLOC USAGE" .rs .sp When the 8-bit library is called through the POSIX interface (see the .\" HREF \fBpcreposix\fP .\" documentation), additional working storage is required for holding the pointers to capturing substrings, because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using \fBmalloc()\fP for each call. The default threshold above which the stack is no longer used is 10; it can be changed by adding a setting such as .sp --with-posix-malloc-threshold=20 .sp to the \fBconfigure\fP command. . . .SH "HANDLING VERY LARGE PATTERNS" .rs .sp Within a compiled pattern, offset values are used to point from one part to another (for example, from an opening parenthesis to an alternation metacharacter). By default, two-byte values are used for these offsets, leading to a maximum size for a compiled pattern of around 64K. This is sufficient to handle all but the most gigantic patterns. Nevertheless, some people do want to process truly enormous patterns, so it is possible to compile PCRE to use three-byte or four-byte offsets by adding a setting such as .sp --with-link-size=3 .sp to the \fBconfigure\fP command. The value given must be 2, 3, or 4. For the 16-bit library, a value of 3 is rounded up to 4. Using longer offsets slows down the operation of PCRE because it has to load additional data when handling them. . . .SH "AVOIDING EXCESSIVE STACK USAGE" .rs .sp When matching with the \fBpcre_exec()\fP function, PCRE implements backtracking by making recursive calls to an internal function called \fBmatch()\fP. In environments where the size of the stack is limited, this can severely limit PCRE's operation. (The Unix environment does not usually suffer from this problem, but it may sometimes be necessary to increase the maximum stack size. There is a discussion in the .\" HREF \fBpcrestack\fP .\" documentation.) 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 .sp --disable-stack-for-recursion .sp to the \fBconfigure\fP command. With this configuration, PCRE will use the \fBpcre_stack_malloc\fP and \fBpcre_stack_free\fP variables to call memory management functions. By default these point to \fBmalloc()\fP and \fBfree()\fP, but you can replace the pointers so that your own functions are used instead. .P Separate functions are provided rather than using \fBpcre_malloc\fP and \fBpcre_free\fP because the usage is very predictable: the block sizes requested are always the same, and the blocks are always freed in reverse order. A calling program might be able to implement optimized functions that perform better than \fBmalloc()\fP and \fBfree()\fP. PCRE runs noticeably more slowly when built in this way. This option affects only the \fBpcre_exec()\fP function; it is not relevant for \fBpcre_dfa_exec()\fP. . . .SH "LIMITING PCRE RESOURCE USAGE" .rs .sp Internally, PCRE has a function called \fBmatch()\fP, which it calls repeatedly (sometimes recursively) when matching a pattern with the \fBpcre_exec()\fP 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 \fBpcre_exec()\fP. The limit can be changed at run time, as described in the .\" HREF \fBpcreapi\fP .\" documentation. The default is 10 million, but this can be changed by adding a setting such as .sp --with-match-limit=500000 .sp to the \fBconfigure\fP command. This setting has no effect on the \fBpcre_dfa_exec()\fP matching function. .P In some environments it is desirable to limit the depth of recursive calls of \fBmatch()\fP 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, .sp --with-match-limit-recursion=10000 .sp to the \fBconfigure\fP command. This value can also be overridden at run time. . . .SH "CREATING CHARACTER TABLES AT BUILD TIME" .rs .sp PCRE uses fixed tables for processing characters whose code values are less than 256. By default, PCRE is built with a set of tables that are distributed in the file \fIpcre_chartables.c.dist\fP. These tables are for ASCII codes only. If you add .sp --enable-rebuild-chartables .sp to the \fBconfigure\fP command, the distributed tables are no longer used. Instead, a program called \fBdftables\fP is compiled and run. This outputs the source for new set of tables, created in the default locale of your C run-time system. (This method of replacing the tables does not work if you are cross compiling, because \fBdftables\fP is run on the local host. If you need to create alternative tables when cross compiling, you will have to do so "by hand".) . . .SH "USING EBCDIC CODE" .rs .sp 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). This is the case for most computer operating systems. PCRE can, however, be compiled to run in an EBCDIC environment by adding .sp --enable-ebcdic .sp to the \fBconfigure\fP command. This setting implies --enable-rebuild-chartables. You should only use it if you know that you are in an EBCDIC environment (for example, an IBM mainframe operating system). The --enable-ebcdic option is incompatible with --enable-utf. . . .SH "PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT" .rs .sp By default, \fBpcregrep\fP reads all files as plain text. You can build it so that it recognizes files whose names end in \fB.gz\fP or \fB.bz2\fP, and reads them with \fBlibz\fP or \fBlibbz2\fP, respectively, by adding one or both of .sp --enable-pcregrep-libz --enable-pcregrep-libbz2 .sp to the \fBconfigure\fP command. These options naturally require that the relevant libraries are installed on your system. Configuration will fail if they are not. . . .SH "PCREGREP BUFFER SIZE" .rs .sp \fBpcregrep\fP uses an internal buffer to hold a "window" on the file it is scanning, in order to be able to output "before" and "after" lines when it finds a match. The size of the buffer is controlled by a parameter whose default value is 20K. The buffer itself is three times this size, but because of the way it is used for holding "before" lines, the longest line that is guaranteed to be processable is the parameter size. You can change the default parameter value by adding, for example, .sp --with-pcregrep-bufsize=50K .sp to the \fBconfigure\fP command. The caller of \fPpcregrep\fP can, however, override this value by specifying a run-time option. . . .SH "PCRETEST OPTION FOR LIBREADLINE SUPPORT" .rs .sp If you add .sp --enable-pcretest-libreadline .sp to the \fBconfigure\fP command, \fBpcretest\fP is linked with the \fBlibreadline\fP library, and when its input is from a terminal, it reads it using the \fBreadline()\fP function. This provides line-editing and history facilities. Note that \fBlibreadline\fP is GPL-licensed, so if you distribute a binary of \fBpcretest\fP linked in this way, there may be licensing issues. .P Setting this option causes the \fB-lreadline\fP option to be added to the \fBpcretest\fP build. In many operating environments with a sytem-installed \fBlibreadline\fP this is sufficient. However, in some environments (e.g. if an unmodified distribution version of readline is in use), some extra configuration may be necessary. The INSTALL file for \fBlibreadline\fP says this: .sp "Readline uses the termcap functions, but does not link with the termcap or curses library itself, allowing applications which link with readline the to choose an appropriate library." .sp If your environment has not been set up so that an appropriate library is automatically included, you may need to add something like .sp LIBS="-ncurses" .sp immediately before the \fBconfigure\fP command. . . .SH "SEE ALSO" .rs .sp \fBpcreapi\fP(3), \fBpcre16\fP, \fBpcre_config\fP(3). . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 07 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcregrep.txt0000644000222100022210000011131111775533017012427 00000000000000PCREGREP(1) PCREGREP(1) NAME pcregrep - a grep with Perl-compatible regular expressions. SYNOPSIS pcregrep [options] [long options] [pattern] [path1 path2 ...] DESCRIPTION pcregrep searches files for character patterns, in the same way as other grep commands do, but it uses the PCRE regular expression library to support patterns that are compatible with the regular expressions of Perl 5. See pcrepattern(3) for a full description of syntax and seman- tics of the regular expressions that PCRE supports. Patterns, whether supplied on the command line or in a separate file, are given without delimiters. For example: pcregrep Thursday /etc/motd If you attempt to use delimiters (for example, by surrounding a pattern with slashes, as is common in Perl scripts), they are interpreted as part of the pattern. Quotes can of course be used to delimit patterns on the command line because they are interpreted by the shell, and indeed they are required if a pattern contains white space or shell metacharacters. The first argument that follows any option settings is treated as the single pattern to be matched when neither -e nor -f is present. Con- versely, when one or both of these options are used to specify pat- terns, all arguments are treated as path names. At least one of -e, -f, or an argument pattern must be provided. If no files are specified, pcregrep reads the standard input. The stan- dard input can also be referenced by a name consisting of a single hyphen. For example: pcregrep some-pattern /file1 - /file3 By default, each line that matches a pattern is copied to the standard output, and if there is more than one file, the file name is output at the start of each line, followed by a colon. However, there are options that can change how pcregrep behaves. In particular, the -M option makes it possible to search for patterns that span line boundaries. What defines a line boundary is controlled by the -N (--newline) option. The amount of memory used for buffering files that are being scanned is controlled by a parameter that can be set by the --buffer-size option. The default value for this parameter is specified when pcregrep is built, with the default default being 20K. A block of memory three times this size is used (to allow for buffering "before" and "after" lines). An error occurs if a line overflows the buffer. Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater. BUFSIZ is defined in . When there is more than one pattern (specified by the use of -e and/or -f), each pattern is applied to each line in the order in which they are defined, except that all the -e patterns are tried before the -f patterns. By default, as soon as one pattern matches (or fails to match when -v is used), no further patterns are considered. However, if --colour (or --color) is used to colour the matching substrings, or if --only-match- ing, --file-offsets, or --line-offsets is used to output only the part of the line that matched (either shown literally, or as an offset), scanning resumes immediately following the match, so that further matches on the same line can be found. If there are multiple patterns, they are all tried on the remainder of the line, but patterns that fol- low the one that matched are not tried on the earlier part of the line. This is the same behaviour as GNU grep, but it does mean that the order in which multiple patterns are specified can affect the output when one of the above options is used. Patterns that can match an empty string are accepted, but empty string matches are never recognized. An example is the pattern "(super)?(man)?", in which all components are optional. This pattern finds all occurrences of both "super" and "man"; the output differs from matching with "super|man" when only the matching substrings are being shown. If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses the value to set a locale when calling the PCRE library. The --locale option can be used to override this. SUPPORT FOR COMPRESSED FILES It is possible to compile pcregrep so that it uses libz or libbz2 to read files whose names end in .gz or .bz2, respectively. You can find out whether your binary has support for one or both of these file types by running it with the --help option. If the appropriate support is not present, files are treated as plain text. The standard input is always so treated. BINARY FILES By default, a file that contains a binary zero byte within the first 1024 bytes is identified as a binary file, and is processed specially. (GNU grep also identifies binary files in this manner.) See the --binary-files option for a means of changing the way binary files are handled. OPTIONS The order in which some of the options appear can affect the output. For example, both the -h and -l options affect the printing of file names. Whichever comes later in the command line will be the one that takes effect. Numerical values for options may be followed by K or M, to signify multiplication by 1024 or 1024*1024 respectively. -- This terminates the list of options. It is useful if the next item on the command line starts with a hyphen but is not an option. This allows for the processing of patterns and file- names that start with hyphens. -A number, --after-context=number Output number lines of context after each matching line. If filenames and/or line numbers are being output, a hyphen sep- arator is used instead of a colon for the context lines. A line containing "--" is output between each group of lines, unless they are in fact contiguous in the input file. The value of number is expected to be relatively small. However, pcregrep guarantees to have up to 8K of following text avail- able for context output. -a, --text Treat binary files as text. This is equivalent to --binary- files=text. -B number, --before-context=number Output number lines of context before each matching line. If filenames and/or line numbers are being output, a hyphen sep- arator is used instead of a colon for the context lines. A line containing "--" is output between each group of lines, unless they are in fact contiguous in the input file. The value of number is expected to be relatively small. However, pcregrep guarantees to have up to 8K of preceding text avail- able for context output. --binary-files=word Specify how binary files are to be processed. If the word is "binary" (the default), pattern matching is performed on binary files, but the only output is "Binary file matches" when a match succeeds. If the word is "text", which is equivalent to the -a or --text option, binary files are processed in the same way as any other file. In this case, when a match succeeds, the output may be binary garbage, which can have nasty effects if sent to a terminal. If the word is "without-match", which is equivalent to the -I option, binary files are not processed at all; they are assumed not to be of interest. --buffer-size=number Set the parameter that controls how much memory is used for buffering files that are being scanned. -C number, --context=number Output number lines of context both before and after each matching line. This is equivalent to setting both -A and -B to the same value. -c, --count Do not output individual lines from the files that are being scanned; instead output the number of lines that would other- wise have been shown. If no lines are selected, the number zero is output. If several files are are being scanned, a count is output for each of them. However, if the --files- with-matches option is also used, only those files whose counts are greater than zero are listed. When -c is used, the -A, -B, and -C options are ignored. --colour, --color If this option is given without any data, it is equivalent to "--colour=auto". If data is required, it must be given in the same shell item, separated by an equals sign. --colour=value, --color=value This option specifies under what circumstances the parts of a line that matched a pattern should be coloured in the output. By default, the output is not coloured. The value (which is optional, see above) may be "never", "always", or "auto". In the latter case, colouring happens only if the standard out- put is connected to a terminal. More resources are used when colouring is enabled, because pcregrep has to search for all possible matches in a line, not just one, in order to colour them all. The colour that is used can be specified by setting the envi- ronment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value of this variable should be a string of two numbers, separated by a semicolon. They are copied directly into the control string for setting colour on a terminal, so it is your responsibility to ensure that they make sense. If neither of the environment variables is set, the default is "1;31", which gives red. -D action, --devices=action If an input path is not a regular file or a directory, "action" specifies how it is to be processed. Valid values are "read" (the default) or "skip" (silently skip the path). -d action, --directories=action If an input path is a directory, "action" specifies how it is to be processed. Valid values are "read" (the default), "recurse" (equivalent to the -r option), or "skip" (silently skip the path). In the default case, directories are read as if they were ordinary files. In some operating systems the effect of reading a directory like this is an immediate end- of-file. -e pattern, --regex=pattern, --regexp=pattern Specify a pattern to be matched. This option can be used mul- tiple times in order to specify several patterns. It can also be used as a way of specifying a single pattern that starts with a hyphen. When -e is used, no argument pattern is taken from the command line; all arguments are treated as file names. There is an overall maximum of 100 patterns. They are applied to each line in the order in which they are defined until one matches (or fails to match if -v is used). If -f is used with -e, the command line patterns are matched first, followed by the patterns from the file, independent of the order in which these options are specified. Note that multi- ple use of -e is not the same as a single pattern with alter- natives. For example, X|Y finds the first character in a line that is X or Y, whereas if the two patterns are given sepa- rately, pcregrep finds X if it is present, even if it follows Y in the line. It finds Y only if there is no X in the line. This really matters only if you are using -o to show the part(s) of the line that matched. --exclude=pattern When pcregrep is searching the files in a directory as a con- sequence of the -r (recursive search) option, any regular files whose names match the pattern are excluded. Subdirecto- ries are not excluded by this option; they are searched recursively, subject to the --exclude-dir and --include_dir options. The pattern is a PCRE regular expression, and is matched against the final component of the file name (not the entire path). If a file name matches both --include and --exclude, it is excluded. There is no short form for this option. --exclude-dir=pattern When pcregrep is searching the contents of a directory as a consequence of the -r (recursive search) option, any subdi- rectories whose names match the pattern are excluded. (Note that the --exclude option does not affect subdirectories.) The pattern is a PCRE regular expression, and is matched against the final component of the name (not the entire path). If a subdirectory name matches both --include-dir and --exclude-dir, it is excluded. There is no short form for this option. -F, --fixed-strings Interpret each pattern as a list of fixed strings, separated by newlines, instead of as a regular expression. The -w (match as a word) and -x (match whole line) options can be used with -F. They apply to each of the fixed strings. A line is selected if any of the fixed strings are found in it (sub- ject to -w or -x, if present). -f filename, --file=filename Read a number of patterns from the file, one per line, and match them against each line of input. A data line is output if any of the patterns match it. The filename can be given as "-" to refer to the standard input. When -f is used, patterns specified on the command line using -e may also be present; they are tested before the file's patterns. However, no other pattern is taken from the command line; all arguments are treated as the names of paths to be searched. There is an overall maximum of 100 patterns. Trailing white space is removed from each line, and blank lines are ignored. An empty file contains no patterns and therefore matches nothing. See also the comments about multiple patterns versus a single pattern with alternatives in the description of -e above. --file-list=filename Read a list of files to be searched from the given file, one per line. Trailing white space is removed from each line, and blank lines are ignored. These files are searched before any others that may be listed on the command line. The filename can be given as "-" to refer to the standard input. If --file and --file-list are both specified as "-", patterns are read first. This is useful only when the standard input is a ter- minal, from which further lines (the list of files) can be read after an end-of-file indication. --file-offsets Instead of showing lines or parts of lines that match, show each match as an offset from the start of the file and a length, separated by a comma. In this mode, no context is shown. That is, the -A, -B, and -C options are ignored. If there is more than one match in a line, each of them is shown separately. This option is mutually exclusive with --line- offsets and --only-matching. -H, --with-filename Force the inclusion of the filename at the start of output lines when searching a single file. By default, the filename is not shown in this case. For matching lines, the filename is followed by a colon; for context lines, a hyphen separator is used. If a line number is also being output, it follows the file name. -h, --no-filename Suppress the output filenames when searching multiple files. By default, filenames are shown when multiple files are searched. For matching lines, the filename is followed by a colon; for context lines, a hyphen separator is used. If a line number is also being output, it follows the file name. --help Output a help message, giving brief details of the command options and file type support, and then exit. -I Treat binary files as never matching. This is equivalent to --binary-files=without-match. -i, --ignore-case Ignore upper/lower case distinctions during comparisons. --include=pattern When pcregrep is searching the files in a directory as a con- sequence of the -r (recursive search) option, only those reg- ular files whose names match the pattern are included. Subdi- rectories are always included and searched recursively, sub- ject to the --include-dir and --exclude-dir options. The pat- tern is a PCRE regular expression, and is matched against the final component of the file name (not the entire path). If a file name matches both --include and --exclude, it is excluded. There is no short form for this option. --include-dir=pattern When pcregrep is searching the contents of a directory as a consequence of the -r (recursive search) option, only those subdirectories whose names match the pattern are included. (Note that the --include option does not affect subdirecto- ries.) The pattern is a PCRE regular expression, and is matched against the final component of the name (not the entire path). If a subdirectory name matches both --include- dir and --exclude-dir, it is excluded. There is no short form for this option. -L, --files-without-match Instead of outputting lines from the files, just output the names of the files that do not contain any lines that would have been output. Each file name is output once, on a sepa- rate line. -l, --files-with-matches Instead of outputting lines from the files, just output the names of the files containing lines that would have been out- put. Each file name is output once, on a separate line. Searching normally stops as soon as a matching line is found in a file. However, if the -c (count) option is also used, matching continues in order to obtain the correct count, and those files that have at least one match are listed along with their counts. Using this option with -c is a way of sup- pressing the listing of files with no matches. --label=name This option supplies a name to be used for the standard input when file names are being output. If not supplied, "(standard input)" is used. There is no short form for this option. --line-buffered When this option is given, input is read and processed line by line, and the output is flushed after each write. By default, input is read in large chunks, unless pcregrep can determine that it is reading from a terminal (which is cur- rently possible only in Unix environments). Output to termi- nal is normally automatically flushed by the operating sys- tem. This option can be useful when the input or output is attached to a pipe and you do not want pcregrep to buffer up large amounts of data. However, its use will affect perfor- mance, and the -M (multiline) option ceases to work. --line-offsets Instead of showing lines or parts of lines that match, show each match as a line number, the offset from the start of the line, and a length. The line number is terminated by a colon (as usual; see the -n option), and the offset and length are separated by a comma. In this mode, no context is shown. That is, the -A, -B, and -C options are ignored. If there is more than one match in a line, each of them is shown sepa- rately. This option is mutually exclusive with --file-offsets and --only-matching. --locale=locale-name This option specifies a locale to be used for pattern match- ing. It overrides the value in the LC_ALL or LC_CTYPE envi- ronment variables. If no locale is specified, the PCRE library's default (usually the "C" locale) is used. There is no short form for this option. --match-limit=number Processing some regular expression patterns can require a very large amount of memory, leading in some cases to a pro- gram crash if not enough is available. Other patterns may take a very long time to search for all possible matching strings. The pcre_exec() function that is called by pcregrep to do the matching has two parameters that can limit the resources that it uses. The --match-limit option provides a means of limiting resource usage when processing patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats. Internally, PCRE uses a func- tion called match() which it calls repeatedly (sometimes recursively). The limit set by --match-limit is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. The --recursion-limit option is similar to --match-limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursive calls, which in turn limits the amount of memory that can be used. The recursion depth is a smaller number than the total number of calls, because not all calls to match() are recursive. This limit is of use only if it is set smaller than --match-limit. There are no short forms for these options. The default set- tings are specified when the PCRE library is compiled, with the default default being 10 million. -M, --multiline Allow patterns to match more than one line. When this option is given, patterns may usefully contain literal newline char- acters and internal occurrences of ^ and $ characters. The output for a successful match may consist of more than one line, the last of which is the one in which the match ended. If the matched string ends with a newline sequence the output ends at the end of that line. When this option is set, the PCRE library is called in "mul- tiline" mode. There is a limit to the number of lines that can be matched, imposed by the way that pcregrep buffers the input file as it scans it. However, pcregrep ensures that at least 8K characters or the rest of the document (whichever is the shorter) are available for forward matching, and simi- larly the previous 8K characters (or all the previous charac- ters, if fewer than 8K) are guaranteed to be available for lookbehind assertions. This option does not work when input is read line by line (see --line-buffered.) -N newline-type, --newline=newline-type The PCRE library supports five different conventions for indicating the ends of lines. They are the single-character sequences CR (carriage return) and LF (linefeed), the two- character sequence CRLF, an "anycrlf" convention, which rec- ognizes any of the preceding three types, and an "any" con- vention, in which any Unicode line ending sequence is assumed to end a line. The Unicode sequences are the three just men- tioned, plus VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). When the PCRE library is built, a default line-ending sequence is specified. This is normally the standard sequence for the operating system. Unless otherwise specified by this option, pcregrep uses the library's default. The possible values for this option are CR, LF, CRLF, ANYCRLF, or ANY. This makes it possible to use pcregrep on files that have come from other environments without having to modify their line endings. If the data that is being scanned does not agree with the convention set by this option, pcregrep may behave in strange ways. -n, --line-number Precede each output line by its line number in the file, fol- lowed by a colon for matching lines or a hyphen for context lines. If the filename is also being output, it precedes the line number. This option is forced if --line-offsets is used. --no-jit If the PCRE library is built with support for just-in-time compiling (which speeds up matching), pcregrep automatically makes use of this, unless it was explicitly disabled at build time. This option can be used to disable the use of JIT at run time. It is provided for testing and working round prob- lems. It should never be needed in normal use. -o, --only-matching Show only the part of the line that matched a pattern instead of the whole line. In this mode, no context is shown. That is, the -A, -B, and -C options are ignored. If there is more than one match in a line, each of them is shown separately. If -o is combined with -v (invert the sense of the match to find non-matching lines), no output is generated, but the return code is set appropriately. If the matched portion of the line is empty, nothing is output unless the file name or line number are being printed, in which case they are shown on an otherwise empty line. This option is mutually exclusive with --file-offsets and --line-offsets. -onumber, --only-matching=number Show only the part of the line that matched the capturing parentheses of the given number. Up to 32 capturing parenthe- ses are supported. Because these options can be given without an argument (see above), if an argument is present, it must be given in the same shell item, for example, -o3 or --only- matching=2. The comments given for the non-argument case above also apply to this case. If the specified capturing parentheses do not exist in the pattern, or were not set in the match, nothing is output unless the file name or line number are being printed. -q, --quiet Work quietly, that is, display nothing except error messages. The exit status indicates whether or not any matches were found. -r, --recursive If any given path is a directory, recursively scan the files it contains, taking note of any --include and --exclude set- tings. By default, a directory is read as a normal file; in some operating systems this gives an immediate end-of-file. This option is a shorthand for setting the -d option to "recurse". --recursion-limit=number See --match-limit above. -s, --no-messages Suppress error messages about non-existent or unreadable files. Such files are quietly skipped. However, the return code is still 2, even if matches were found in other files. -u, --utf-8 Operate in UTF-8 mode. This option is available only if PCRE has been compiled with UTF-8 support. Both patterns and sub- ject lines must be valid strings of UTF-8 characters. -V, --version Write the version numbers of pcregrep and the PCRE library that is being used to the standard error stream. -v, --invert-match Invert the sense of the match, so that lines which do not match any of the patterns are the ones that are found. -w, --word-regex, --word-regexp Force the patterns to match only whole words. This is equiva- lent to having \b at the start and end of the pattern. -x, --line-regex, --line-regexp Force the patterns to be anchored (each must start matching at the beginning of a line) and in addition, require them to match entire lines. This is equivalent to having ^ and $ characters at the start and end of each alternative branch in every pattern. ENVIRONMENT VARIABLES The environment variables LC_ALL and LC_CTYPE are examined, in that order, for a locale. The first one that is set is used. This can be overridden by the --locale option. If no locale is set, the PCRE library's default (usually the "C" locale) is used. NEWLINES The -N (--newline) option allows pcregrep to scan files with different newline conventions from the default. However, the setting of this option does not affect the way in which pcregrep writes information to the standard error and output streams. It uses the string "\n" in C printf() calls to indicate newlines, relying on the C I/O library to convert this to an appropriate sequence if the output is sent to a file. OPTIONS COMPATIBILITY Many of the short and long forms of pcregrep's options are the same as in the GNU grep program. Any long option of the form --xxx-regexp (GNU terminology) is also available as --xxx-regex (PCRE terminology). How- ever, the --file-list, --file-offsets, --include-dir, --line-offsets, --locale, --match-limit, -M, --multiline, -N, --newline, --recursion- limit, -u, and --utf-8 options are specific to pcregrep, as is the use of the --only-matching option with a capturing parentheses number. Although most of the common options work the same way, a few are dif- ferent in pcregrep. For example, the --include option's argument is a glob for GNU grep, but a regular expression for pcregrep. If both the -c and -l options are given, GNU grep lists only file names, without counts, but pcregrep gives the counts. OPTIONS WITH DATA There are four different ways in which an option with data can be spec- ified. If a short form option is used, the data may follow immedi- ately, or (with one exception) in the next command line item. For exam- ple: -f/some/file -f /some/file The exception is the -o option, which may appear with or without data. Because of this, if data is present, it must follow immediately in the same item, for example -o3. If a long form option is used, the data may appear in the same command line item, separated by an equals character, or (with two exceptions) it may appear in the next command line item. For example: --file=/some/file --file /some/file Note, however, that if you want to supply a file name beginning with ~ as data in a shell command, and have the shell expand ~ to a home directory, you must separate the file name from the option, because the shell does not treat ~ specially unless it is at the start of an item. The exceptions to the above are the --colour (or --color) and --only- matching options, for which the data is optional. If one of these options does have data, it must be given in the first form, using an equals character. Otherwise pcregrep will assume that it has no data. MATCHING ERRORS It is possible to supply a regular expression that takes a very long time to fail to match certain lines. Such patterns normally involve nested indefinite repeats, for example: (a+)*\d when matched against a line of a's with no final digit. The PCRE matching function has a resource limit that causes it to abort in these circumstances. If this happens, pcregrep outputs an error message and the line that caused the problem to the standard error stream. If there are more than 20 such errors, pcregrep gives up. The --match-limit option of pcregrep can be used to set the overall resource limit; there is a second option called --recursion-limit that sets a limit on the amount of memory (usually stack) that is used (see the discussion of these options above). DIAGNOSTICS Exit status is 0 if any matches were found, 1 if no matches were found, and 2 for syntax errors, overlong lines, non-existent or inaccessible files (even if matches were found in other files) or too many matching errors. Using the -s option to suppress error messages about inaccessi- ble files does not affect the return code. SEE ALSO pcrepattern(3), pcretest(1). AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 04 March 2012 Copyright (c) 1997-2012 University of Cambridge. pcre-8.31/doc/pcreperform.30000644000222100022210000001622111735643337012476 00000000000000.TH PCREPERFORM 3 "09 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE PERFORMANCE" .rs .sp Two aspects of performance are discussed below: memory usage and processing time. The way you express your pattern as a regular expression can affect both of them. . .SH "COMPILED PATTERN MEMORY USAGE" .rs .sp Patterns are compiled by PCRE into a reasonably efficient interpretive code, so that most simple patterns do not use much memory. However, there is one case where the memory usage of a compiled pattern can be unexpectedly large. If a parenthesized subpattern has a quantifier with a minimum greater than 1 and/or a limited maximum, the whole subpattern is repeated in the compiled code. For example, the pattern .sp (abc|def){2,4} .sp is compiled as if it were .sp (abc|def)(abc|def)((abc|def)(abc|def)?)? .sp (Technical aside: It is done this way so that backtrack points within each of the repetitions can be independently maintained.) .P For regular expressions whose quantifiers use only small numbers, this is not usually a problem. However, if the numbers are large, and particularly if such repetitions are nested, the memory usage can become an embarrassment. For example, the very simple pattern .sp ((ab){1,1000}c){1,3} .sp uses 51K bytes when compiled using the 8-bit library. When PCRE is compiled with its default internal pointer size of two bytes, the size limit on a compiled pattern is 64K data units, and this is reached with the above pattern if the outer repetition is increased from 3 to 4. PCRE can be compiled to use larger internal pointers and thus handle larger compiled patterns, but it is better to try to rewrite your pattern to use less memory if you can. .P One way of reducing the memory usage for such patterns is to make use of PCRE's .\" HTML .\" "subroutine" .\" facility. Re-writing the above pattern as .sp ((ab)(?2){0,999}c)(?1){0,2} .sp reduces the memory requirements to 18K, and indeed it remains under 20K even with the outer repetition increased to 100. However, this pattern is not exactly equivalent, because the "subroutine" calls are treated as .\" HTML .\" atomic groups .\" into which there can be no backtracking if there is a subsequent matching failure. Therefore, PCRE cannot do this kind of rewriting automatically. Furthermore, there is a noticeable loss of speed when executing the modified pattern. Nevertheless, if the atomic grouping is not a problem and the loss of speed is acceptable, this kind of rewriting will allow you to process patterns that PCRE cannot otherwise handle. . . .SH "STACK USAGE AT RUN TIME" .rs .sp When \fBpcre_exec()\fP or \fBpcre16_exec()\fP is used for matching, certain kinds of pattern can cause it to use large amounts of the process stack. In some environments the default process stack is quite small, and if it runs out the result is often SIGSEGV. This issue is probably the most frequently raised problem with PCRE. Rewriting your pattern can often help. The .\" HREF \fBpcrestack\fP .\" documentation discusses this issue in detail. . . .SH "PROCESSING TIME" .rs .sp Certain items in regular expression patterns are processed more efficiently than others. It is more efficient to use a character class like [aeiou] than a set of single-character alternatives such as (a|e|i|o|u). In general, the simplest construction that provides the required behaviour is usually the most efficient. Jeffrey Friedl's book contains a lot of useful general discussion about optimizing regular expressions for efficient performance. This document contains a few observations about PCRE. .P Using Unicode character properties (the \ep, \eP, and \eX escapes) is slow, because PCRE has to scan a structure that contains data for over fifteen thousand characters whenever it needs a character's property. If you can find an alternative pattern that does not use character properties, it will probably be faster. .P By default, the escape sequences \eb, \ed, \es, and \ew, and the POSIX character classes such as [:alpha:] do not use Unicode properties, partly for backwards compatibility, and partly for performance reasons. However, you can set PCRE_UCP if you want Unicode character properties to be used. This can double the matching time for items such as \ed, when matched with a traditional matching function; the performance loss is less with a DFA matching function, and in both cases there is not much difference for \eb. .P When a pattern begins with .* not in parentheses, or in parentheses that are not the subject of a backreference, and the PCRE_DOTALL option is set, the pattern is implicitly anchored by PCRE, since it can match only at the start of a subject string. However, if PCRE_DOTALL is not set, PCRE cannot make this optimization, because the . metacharacter does not then match a newline, and if the subject string contains newlines, the pattern may match from the character immediately following one of them instead of from the very start. For example, the pattern .sp .*second .sp matches the subject "first\enand second" (where \en stands for a newline character), with the match starting at the seventh character. In order to do this, PCRE has to retry the match starting after every newline in the subject. .P If you are using such a pattern with subject strings that do not contain newlines, the best performance is obtained by setting PCRE_DOTALL, or starting the pattern with ^.* or ^.*? to indicate explicit anchoring. That saves PCRE from having to scan along the subject looking for a newline to restart at. .P Beware of patterns that contain nested indefinite repeats. These can take a long time to run when applied to a string that does not match. Consider the pattern fragment .sp ^(a+)* .sp This can match "aaaa" in 16 different ways, and this number increases very rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4 times, and for each of those cases other than 0 or 4, the + repeats can match different numbers of times.) When the remainder of the pattern is such that the entire match is going to fail, PCRE has in principle to try every possible variation, and this can take an extremely long time, even for relatively short strings. .P An optimization catches some of the more simple cases such as .sp (a+)*b .sp where a literal character follows. Before embarking on the standard matching procedure, PCRE checks that there is a "b" later in the subject string, and if there is not, it fails the match immediately. However, when there is no following literal this optimization cannot be used. You can see the difference by comparing the behaviour of .sp (a+)*\ed .sp with the pattern above. The former gives a failure almost instantly when applied to a whole line of "a" characters, whereas the latter takes an appreciable time with strings longer than about 20 characters. .P In many cases, the solution to this kind of performance issue is to use an atomic group or a possessive quantifier. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 09 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcreapi.30000644000222100022210000034226111767405630011600 00000000000000.TH PCREAPI 3 "04 May 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions .sp .B #include . . .SH "PCRE NATIVE API BASIC FUNCTIONS" .rs .sp .SM .B pcre *pcre_compile(const char *\fIpattern\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .PP .B pcre *pcre_compile2(const char *\fIpattern\fP, int \fIoptions\fP, .ti +5n .B int *\fIerrorcodeptr\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .PP .B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP); .PP .B void pcre_free_study(pcre_extra *\fIextra\fP); .PP .B int pcre_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); .PP .B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, .ti +5n .B int *\fIworkspace\fP, int \fIwscount\fP); . . .SH "PCRE NATIVE API STRING EXTRACTION FUNCTIONS" .rs .sp .B int pcre_copy_named_substring(const pcre *\fIcode\fP, .ti +5n .B const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B char *\fIbuffer\fP, int \fIbuffersize\fP); .PP .B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, .ti +5n .B int \fIbuffersize\fP); .PP .B int pcre_get_named_substring(const pcre *\fIcode\fP, .ti +5n .B const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B const char **\fIstringptr\fP); .PP .B int pcre_get_stringnumber(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP); .PP .B int pcre_get_stringtable_entries(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP); .PP .B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, .ti +5n .B const char **\fIstringptr\fP); .PP .B int pcre_get_substring_list(const char *\fIsubject\fP, .ti +5n .B int *\fIovector\fP, int \fIstringcount\fP, "const char ***\fIlistptr\fP);" .PP .B void pcre_free_substring(const char *\fIstringptr\fP); .PP .B void pcre_free_substring_list(const char **\fIstringptr\fP); . . .SH "PCRE NATIVE API AUXILIARY FUNCTIONS" .rs .sp .B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); .PP .B void pcre_jit_stack_free(pcre_jit_stack *\fIstack\fP); .PP .B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP, .ti +5n .B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP); .PP .B const unsigned char *pcre_maketables(void); .PP .B int pcre_fullinfo(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B int \fIwhat\fP, void *\fIwhere\fP); .PP .B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); .PP .B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); .PP .B const char *pcre_version(void); .PP .B int pcre_pattern_to_host_byte_order(pcre *\fIcode\fP, .ti +5n .B pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP); . . .SH "PCRE NATIVE API INDIRECTED FUNCTIONS" .rs .sp .B void *(*pcre_malloc)(size_t); .PP .B void (*pcre_free)(void *); .PP .B void *(*pcre_stack_malloc)(size_t); .PP .B void (*pcre_stack_free)(void *); .PP .B int (*pcre_callout)(pcre_callout_block *); . . .SH "PCRE 8-BIT AND 16-BIT LIBRARIES" .rs .sp From release 8.30, PCRE can be compiled as a library for handling 16-bit character strings as well as, or instead of, the original library that handles 8-bit character strings. To avoid too much complication, this document describes the 8-bit versions of the functions, with only occasional references to the 16-bit library. .P The 16-bit functions operate in the same way as their 8-bit counterparts; they just use different data types for their arguments and results, and their names start with \fBpcre16_\fP instead of \fBpcre_\fP. For every option that has UTF8 in its name (for example, PCRE_UTF8), there is a corresponding 16-bit name with UTF8 replaced by UTF16. This facility is in fact just cosmetic; the 16-bit option names define the same bit values. .P References to bytes and UTF-8 in this document should be read as references to 16-bit data quantities and UTF-16 when using the 16-bit library, unless specified otherwise. More details of the specific differences for the 16-bit library are given in the .\" HREF \fBpcre16\fP .\" page. . . .SH "PCRE API OVERVIEW" .rs .sp PCRE has its own native API, which is described in this document. There are also some wrapper functions (for the 8-bit library only) that correspond to the POSIX regular expression API, but they do not give access to all the functionality. They are described in the .\" HREF \fBpcreposix\fP .\" documentation. Both of these APIs define a set of C function calls. A C++ wrapper (again for the 8-bit library only) is also distributed with PCRE. It is documented in the .\" HREF \fBpcrecpp\fP .\" page. .P The native API C function prototypes are defined in the header file \fBpcre.h\fP, and on Unix-like systems the (8-bit) library itself is called \fBlibpcre\fP. It can normally be accessed by adding \fB-lpcre\fP to the command for linking an application that uses PCRE. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release numbers for the library. Applications can use these to include support for different releases of PCRE. .P In a Windows environment, if you want to statically link an application program against a non-dll \fBpcre.a\fP file, you must define PCRE_STATIC before including \fBpcre.h\fP or \fBpcrecpp.h\fP, because otherwise the \fBpcre_malloc()\fP and \fBpcre_free()\fP exported functions will be declared \fB__declspec(dllimport)\fP, with unwanted results. .P The functions \fBpcre_compile()\fP, \fBpcre_compile2()\fP, \fBpcre_study()\fP, and \fBpcre_exec()\fP are used for compiling and matching regular expressions in a Perl-compatible manner. A sample program that demonstrates the simplest way of using them is provided in the file called \fIpcredemo.c\fP in the PCRE source distribution. A listing of this program is given in the .\" HREF \fBpcredemo\fP .\" documentation, and the .\" HREF \fBpcresample\fP .\" documentation describes how to compile and run it. .P Just-in-time compiler support is an optional feature of PCRE that can be built in appropriate hardware environments. It greatly speeds up the matching performance of many patterns. Simple programs can easily request that it be used if available, by setting an option that is ignored when it is not relevant. More complicated programs might need to make use of the functions \fBpcre_jit_stack_alloc()\fP, \fBpcre_jit_stack_free()\fP, and \fBpcre_assign_jit_stack()\fP in order to control the JIT code's memory usage. These functions are discussed in the .\" HREF \fBpcrejit\fP .\" documentation. .P A second matching function, \fBpcre_dfa_exec()\fP, which is not Perl-compatible, is also provided. This uses a different algorithm for the matching. The alternative algorithm finds all possible matches (at a given point in the subject), and scans the subject just once (unless there are lookbehind assertions). However, this algorithm does not return captured substrings. A description of the two matching algorithms and their advantages and disadvantages is given in the .\" HREF \fBpcrematching\fP .\" documentation. .P In addition to the main compiling and matching functions, there are convenience functions for extracting captured substrings from a subject string that is matched by \fBpcre_exec()\fP. They are: .sp \fBpcre_copy_substring()\fP \fBpcre_copy_named_substring()\fP \fBpcre_get_substring()\fP \fBpcre_get_named_substring()\fP \fBpcre_get_substring_list()\fP \fBpcre_get_stringnumber()\fP \fBpcre_get_stringtable_entries()\fP .sp \fBpcre_free_substring()\fP and \fBpcre_free_substring_list()\fP are also provided, to free the memory used for extracted strings. .P The function \fBpcre_maketables()\fP is used to build a set of character tables in the current locale for passing to \fBpcre_compile()\fP, \fBpcre_exec()\fP, or \fBpcre_dfa_exec()\fP. This is an optional facility that is provided for specialist use. Most commonly, no special tables are passed, in which case internal tables that are generated when PCRE is built are used. .P The function \fBpcre_fullinfo()\fP is used to find out information about a compiled pattern. The function \fBpcre_version()\fP returns a pointer to a string containing the version of PCRE and its date of release. .P The function \fBpcre_refcount()\fP maintains a reference count in a data block containing a compiled pattern. This is provided for the benefit of object-oriented applications. .P The global variables \fBpcre_malloc\fP and \fBpcre_free\fP initially contain the entry points of the standard \fBmalloc()\fP and \fBfree()\fP functions, respectively. PCRE calls the memory management functions via these variables, so a calling program can replace them if it wishes to intercept the calls. This should be done before calling any PCRE functions. .P The global variables \fBpcre_stack_malloc\fP and \fBpcre_stack_free\fP are also 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 \fBpcre_exec()\fP function. See the .\" HREF \fBpcrebuild\fP .\" documentation for details of how to do this. It is a non-standard way of building PCRE, for use in environments 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 .\" HREF \fBpcrestack\fP .\" documentation. .P The global variable \fBpcre_callout\fP initially contains NULL. It can be set by the caller to a "callout" function, which PCRE will then call at specified points during a matching operation. Details are given in the .\" HREF \fBpcrecallout\fP .\" documentation. . . .\" HTML .SH NEWLINES .rs .sp PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (linefeed) character, the two-character sequence CRLF, any of the three preceding, or any Unicode newline sequence. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). .P Each of the first three conventions is used by at least one operating system as its standard newline sequence. 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. .P At compile time, the newline convention can be specified by the \fIoptions\fP argument of \fBpcre_compile()\fP, or it can be specified by special text at the start of the pattern itself; this overrides any other settings. See the .\" HREF \fBpcrepattern\fP .\" page for details of the special character sequences. .P In the PCRE documentation the word "newline" is used to mean "the character or pair of characters that indicate a line break". The choice of newline convention affects the handling of the dot, circumflex, and dollar metacharacters, the handling of #-comments in /x mode, and, when CRLF is a recognized line ending sequence, the match position advancement for a non-anchored pattern. There is more detail about this in the .\" HTML .\" section on \fBpcre_exec()\fP options .\" below. .P The choice of newline convention does not affect the interpretation of the \en or \er escape sequences, nor does it affect what \eR matches, which is controlled in a similar way, but by separate options. . . .SH MULTITHREADING .rs .sp The PCRE functions can be used in multi-threading applications, with the proviso that the memory management functions pointed to by \fBpcre_malloc\fP, \fBpcre_free\fP, \fBpcre_stack_malloc\fP, and \fBpcre_stack_free\fP, and the callout function pointed to by \fBpcre_callout\fP, are shared by all threads. .P The compiled form of a regular expression is not altered during matching, so the same compiled pattern can safely be used by several threads at once. .P If the just-in-time optimization feature is being used, it needs separate memory stack areas for each thread. See the .\" HREF \fBpcrejit\fP .\" documentation for more details. . . .SH "SAVING PRECOMPILED PATTERNS FOR LATER USE" .rs .sp 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 .\" HREF \fBpcreprecompile\fP .\" documentation, which includes a description of the \fBpcre_pattern_to_host_byte_order()\fP function. However, compiling a regular expression with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes. . . .SH "CHECKING BUILD-TIME OPTIONS" .rs .sp .B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); .PP The function \fBpcre_config()\fP makes it possible for a PCRE client to discover which optional features have been compiled into the PCRE library. The .\" HREF \fBpcrebuild\fP .\" documentation has more details about these optional features. .P The first argument for \fBpcre_config()\fP is an integer, specifying which information is required; the second argument is a pointer to a variable into which the information is placed. The returned value is zero on success, or the negative error code PCRE_ERROR_BADOPTION if the value in the first argument is not recognized. The following information is available: .sp PCRE_CONFIG_UTF8 .sp The output is an integer that is set to one if UTF-8 support is available; otherwise it is set to zero. If this option is given to the 16-bit version of this function, \fBpcre16_config()\fP, the result is PCRE_ERROR_BADOPTION. .sp PCRE_CONFIG_UTF16 .sp The output is an integer that is set to one if UTF-16 support is available; otherwise it is set to zero. This value should normally be given to the 16-bit version of this function, \fBpcre16_config()\fP. If it is given to the 8-bit version of this function, the result is PCRE_ERROR_BADOPTION. .sp PCRE_CONFIG_UNICODE_PROPERTIES .sp The output is an integer that is set to one if support for Unicode character properties is available; otherwise it is set to zero. .sp PCRE_CONFIG_JIT .sp The output is an integer that is set to one if support for just-in-time compiling is available; otherwise it is set to zero. .sp PCRE_CONFIG_JITTARGET .sp The output is a pointer to a zero-terminated "const char *" string. If JIT support is available, the string contains the name of the architecture for which the JIT compiler is configured, for example "x86 32bit (little endian + unaligned)". If JIT support is not available, the result is NULL. .sp PCRE_CONFIG_NEWLINE .sp The output is an integer whose value specifies the default character sequence that is recognized as meaning "newline". The four values that are supported are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for ANYCRLF, and -1 for ANY. Though they are derived from ASCII, the same values are returned in EBCDIC environments. The default should normally correspond to the standard sequence for your operating system. .sp PCRE_CONFIG_BSR .sp The output is an integer whose value indicates what character sequences the \eR escape sequence matches by default. A value of 0 means that \eR matches any Unicode line ending sequence; a value of 1 means that \eR matches only CR, LF, or CRLF. The default can be overridden when a pattern is compiled or matched. .sp PCRE_CONFIG_LINK_SIZE .sp The output is an integer that contains the number of bytes used for internal linkage in compiled regular expressions. For the 8-bit library, the value can be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still a number of bytes. 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. Larger values allow larger regular expressions to be compiled, at the expense of slower matching. .sp PCRE_CONFIG_POSIX_MALLOC_THRESHOLD .sp The output is an integer that contains the threshold above which the POSIX interface uses \fBmalloc()\fP for output vectors. Further details are given in the .\" HREF \fBpcreposix\fP .\" documentation. .sp PCRE_CONFIG_MATCH_LIMIT .sp The output is a long integer that gives the default limit for the number of internal matching function calls in a \fBpcre_exec()\fP execution. Further details are given with \fBpcre_exec()\fP below. .sp PCRE_CONFIG_MATCH_LIMIT_RECURSION .sp The output is a long integer that gives the default limit for the depth of recursion when calling the internal matching function in a \fBpcre_exec()\fP execution. Further details are given with \fBpcre_exec()\fP below. .sp PCRE_CONFIG_STACKRECURSE .sp The output is an integer that is set to one if internal recursion when running \fBpcre_exec()\fP is implemented by recursive function calls that use 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, \fBpcre_stack_malloc\fP and \fBpcre_stack_free\fP are called to manage memory blocks on the heap, thus avoiding the use of the stack. . . .SH "COMPILING A PATTERN" .rs .sp .B pcre *pcre_compile(const char *\fIpattern\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .sp .B pcre *pcre_compile2(const char *\fIpattern\fP, int \fIoptions\fP, .ti +5n .B int *\fIerrorcodeptr\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .P Either of the functions \fBpcre_compile()\fP or \fBpcre_compile2()\fP can be called to compile a pattern into an internal form. The only difference between the two interfaces is that \fBpcre_compile2()\fP has an additional argument, \fIerrorcodeptr\fP, via which a numerical error code can be returned. To avoid too much repetition, we refer just to \fBpcre_compile()\fP below, but the information applies equally to \fBpcre_compile2()\fP. .P The pattern is a C string terminated by a binary zero, and is passed in the \fIpattern\fP argument. A pointer to a single block of memory that is obtained via \fBpcre_malloc\fP is returned. This contains the compiled code and related data. The \fBpcre\fP 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 (via \fBpcre_free\fP) when it is no longer required. .P Although the compiled code of a PCRE regex is relocatable, that is, it does not depend on memory location, the complete \fBpcre\fP data block is not fully relocatable, because it may contain a copy of the \fItableptr\fP argument, which is an address (see below). .P The \fIoptions\fP argument contains various bit settings that affect the compilation. 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, but some others as well) can also be set and unset from within the pattern (see the detailed description in the .\" HREF \fBpcrepattern\fP .\" documentation). For those options that can be different in different parts of the pattern, the contents of the \fIoptions\fP argument specifies their settings at the start of compilation and execution. The PCRE_ANCHORED, PCRE_BSR_\fIxxx\fP, PCRE_NEWLINE_\fIxxx\fP, PCRE_NO_UTF8_CHECK, and PCRE_NO_START_OPTIMIZE options can be set at the time of matching as well as at compile time. .P If \fIerrptr\fP is NULL, \fBpcre_compile()\fP returns NULL immediately. Otherwise, if compilation of a pattern fails, \fBpcre_compile()\fP returns NULL, and sets the variable pointed to by \fIerrptr\fP 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. Normally, the offset from the start of the pattern to the byte that was being processed when the error was discovered is placed in the variable pointed to by \fIerroffset\fP, which must not be NULL (if it is, an immediate error is given). However, for an invalid UTF-8 string, the offset is that of the first byte of the failing character. .P Some errors are not detected until the whole pattern has been scanned; in these cases, the offset passed back is the length of the pattern. Note that the offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point into the middle of a UTF-8 character. .P If \fBpcre_compile2()\fP is used instead of \fBpcre_compile()\fP, and the \fIerrorcodeptr\fP 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. .P If the final argument, \fItableptr\fP, is NULL, PCRE uses a default set of character tables that are built when PCRE is compiled, using the default C locale. Otherwise, \fItableptr\fP must be an address that is the result of a call to \fBpcre_maketables()\fP. This value is stored with the compiled pattern, and used again by \fBpcre_exec()\fP, unless another table pointer is passed to it. For more discussion, see the section on locale support below. .P This code fragment shows a typical straightforward call to \fBpcre_compile()\fP: .sp pcre *re; const char *error; int erroffset; re = pcre_compile( "^A.*Z", /* the pattern */ 0, /* default options */ &error, /* for error message */ &erroffset, /* for error offset */ NULL); /* use default character tables */ .sp The following names for option bits are defined in the \fBpcre.h\fP header file: .sp PCRE_ANCHORED .sp 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 only way to do it in Perl. .sp PCRE_AUTO_CALLOUT .sp If this bit is set, \fBpcre_compile()\fP automatically inserts callout items, all with number 255, before each pattern item. For discussion of the callout facility, see the .\" HREF \fBpcrecallout\fP .\" documentation. .sp PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE .sp These options (which are mutually exclusive) control what the \eR escape sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. The default is specified when PCRE is built. It can be overridden from within the pattern, or by setting an option when a compiled pattern is matched. .sp PCRE_CASELESS .sp 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 compiled 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. .sp PCRE_DOLLAR_ENDONLY .sp 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. .sp PCRE_DOTALL .sp If this bit is set, a dot metacharacter in the pattern matches a character of any value, including one that indicates a newline. However, it only ever matches one character, even if newlines are coded as CRLF. Without this option, 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 newline characters, independent of the setting of this option. .sp PCRE_DUPNAMES .sp 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 .\" HREF \fBpcrepattern\fP .\" documentation. .sp PCRE_EXTENDED .sp If this bit is set, white space 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, characters between an unescaped # outside a character class and the next newline, 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. .P Which characters are interpreted as newlines is controlled by the options passed to \fBpcre_compile()\fP or by a special sequence at the start of the pattern, as described in the section entitled .\" HTML .\" "Newline conventions" .\" in the \fBpcrepattern\fP documentation. Note that the end of this type of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. .P This option makes it possible to include comments inside complicated patterns. Note, however, that this applies only to data characters. White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that introduces a conditional subpattern. .sp PCRE_EXTRA .sp 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 an error for this, by running it with the -w option.) There are at present no other features controlled by this option. It can also be set by a (?X) option setting within a pattern. .sp PCRE_FIRSTLINE .sp If this option is set, an unanchored pattern is required to match before or at the first newline in the subject string, though the matched text may continue over the newline. .sp PCRE_JAVASCRIPT_COMPAT .sp If this option is set, PCRE's behaviour is changed in some ways so that it is compatible with JavaScript rather than Perl. The changes are as follows: .P (1) A lone closing square bracket in a pattern causes a compile-time error, because this is illegal in JavaScript (by default it is treated as a data character). Thus, the pattern AB]CD becomes illegal when this option is set. .P (2) At run time, a back reference to an unset subpattern group matches an empty string (by default this causes the current matching alternative to fail). A pattern such as (\e1)(a) succeeds when this option is set (assuming it can find an "a" in the subject), whereas it fails by default, for Perl compatibility. .P (3) \eU matches an upper case "U" character; by default \eU causes a compile time error (Perl uses \eU to upper case subsequent characters). .P (4) \eu matches a lower case "u" character unless it is followed by four hexadecimal digits, in which case the hexadecimal number defines the code point to match. By default, \eu causes a compile time error (Perl uses it to upper case the following character). .P (5) \ex matches a lower case "x" character unless it is followed by two hexadecimal digits, in which case the hexadecimal number defines the code point to match. By default, as in Perl, a hexadecimal number is always expected after \ex, but it may have zero, one, or two digits (so, for example, \exz matches a binary zero character followed by z). .sp PCRE_MULTILINE .sp By default, PCRE treats the subject string as consisting of a single line of characters (even if it actually contains newlines). The "start of line" metacharacter (^) matches only at the start of the string, while the "end of line" metacharacter ($) matches only at the end of the string, or before a terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as Perl. .P When PCRE_MULTILINE it is set, the "start of line" and "end of line" 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 newlines in a subject string, or no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. .sp PCRE_NEWLINE_CR PCRE_NEWLINE_LF PCRE_NEWLINE_CRLF PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY .sp 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 PCRE_NEWLINE_CRLF specifies that a newline is indicated by the two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies that any of the three preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit library, the last two are recognized only in UTF-8 mode. .P The newline setting in the options word uses three bits that are treated as a number, giving eight possibilities. Currently only six are used (default plus the five values above). This means that if you set more than one newline option, the combination may or may not be sensible. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and cause an error. .P The only time that a line break in a pattern is specially recognized when compiling is when PCRE_EXTENDED is set. CR and LF are white space characters, and so are ignored in this mode. Also, an unescaped # outside a character class indicates a comment that lasts until after the next line break sequence. In other circumstances, line break sequences in patterns are treated as literal data. .P The newline option that is set at compile time becomes the default that is used for \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, but it can be overridden. .sp PCRE_NO_AUTO_CAPTURE .sp If this option is set, it disables the use of numbered capturing parentheses 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. .sp NO_START_OPTIMIZE .sp This is an option that acts at matching time; that is, it is really an option for \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. If it is set at compile time, it is remembered with the compiled pattern and assumed at matching time. For details see the discussion of PCRE_NO_START_OPTIMIZE .\" HTML .\" below. .\" .sp PCRE_UCP .sp This option changes the way PCRE processes \eB, \eb, \eD, \ed, \eS, \es, \eW, \ew, and some of the POSIX character classes. By default, only ASCII characters are recognized, but if PCRE_UCP is set, Unicode properties are used instead to classify characters. More details are given in the section on .\" HTML .\" generic character types .\" in the .\" HREF \fBpcrepattern\fP .\" page. If you set PCRE_UCP, matching one of the items it affects takes much longer. The option is available only if PCRE has been compiled with Unicode property support. .sp PCRE_UNGREEDY .sp 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. .sp PCRE_UTF8 .sp This option causes PCRE to regard both the pattern and the subject as strings of UTF-8 characters instead of single-byte strings. However, it is available only when PCRE is built to include UTF support. If not, the use of this option provokes an error. Details of how this option changes the behaviour of PCRE are given in the .\" HREF \fBpcreunicode\fP .\" page. .sp PCRE_NO_UTF8_CHECK .sp When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is automatically checked. There is a discussion about the .\" HTML .\" validity of UTF-8 strings .\" in the .\" HREF \fBpcreunicode\fP .\" page. If an invalid UTF-8 sequence is found, \fBpcre_compile()\fP 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 \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, to suppress the validity checking of subject strings. . . .SH "COMPILATION ERROR CODES" .rs .sp The following table lists the error codes than may be returned by \fBpcre_compile2()\fP, along with the error messages that may be returned by both compiling functions. Note that error messages are always 8-bit ASCII strings, even in 16-bit mode. As PCRE has developed, some error codes have fallen out of use. To avoid confusion, they have not been re-used. .sp 0 no error 1 \e at end of pattern 2 \ec at end of pattern 3 unrecognized character follows \e 4 numbers out of order in {} quantifier 5 number too big in {} quantifier 6 missing terminating ] for character class 7 invalid escape sequence in character class 8 range out of order in character class 9 nothing to repeat 10 [this code is not in use] 11 internal error: unexpected repeat 12 unrecognized character after (? or (?- 13 POSIX named classes are supported only within a class 14 missing ) 15 reference to non-existent subpattern 16 erroffset passed as NULL 17 unknown option bit(s) set 18 missing ) after comment 19 [this code is not in use] 20 regular expression is too large 21 failed to get memory 22 unmatched parentheses 23 internal error: code overflow 24 unrecognized character after (?< 25 lookbehind assertion is not fixed length 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 ) 30 unknown POSIX class name 31 POSIX collating elements are not supported 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] 34 character value in \ex{...} sequence is too large 35 invalid condition (?(0) 36 \eC not allowed in lookbehind assertion 37 PCRE does not support \eL, \el, \eN{name}, \eU, or \eu 38 number after (?C is > 255 39 closing ) for (?C expected 40 recursive call could loop indefinitely 41 unrecognized character after (?P 42 syntax error in subpattern name (missing terminator) 43 two named subpatterns have the same name 44 invalid UTF-8 string (specifically UTF-8) 45 support for \eP, \ep, and \eX has not been compiled 46 malformed \eP or \ep sequence 47 unknown property name after \eP or \ep 48 subpattern name is too long (maximum 32 characters) 49 too many named subpatterns (maximum 10000) 50 [this code is not in use] 51 octal value is greater than \e377 in 8-bit non-UTF-8 mode 52 internal error: overran compiling workspace 53 internal error: previously-checked referenced subpattern not found 54 DEFINE group contains more than one branch 55 repeating a DEFINE group is not allowed 56 inconsistent NEWLINE options 57 \eg is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number 58 a numbered reference must not be zero 59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) 60 (*VERB) not recognized 61 number is too big 62 subpattern name expected 63 digit expected after (?+ 64 ] is an invalid data character in JavaScript compatibility mode 65 different names for subpatterns of the same number are not allowed 66 (*MARK) must have an argument 67 this version of PCRE is not compiled with Unicode property support 68 \ec must be followed by an ASCII character 69 \ek is not followed by a braced, angle-bracketed, or quoted name 70 internal error: unknown opcode in find_fixedlength() 71 \eN is not supported in a class 72 too many forward references 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff) 74 invalid UTF-16 string (specifically UTF-16) 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) 76 character value in \eu.... sequence is too large .sp The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. . . .\" HTML .SH "STUDYING A PATTERN" .rs .sp .B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP .ti +5n .B const char **\fIerrptr\fP); .PP 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 \fBpcre_study()\fP takes a pointer to a compiled pattern as its first argument. If studying the pattern produces additional information that will help speed up matching, \fBpcre_study()\fP returns a pointer to a \fBpcre_extra\fP block, in which the \fIstudy_data\fP field points to the results of the study. .P The returned value from \fBpcre_study()\fP can be passed directly to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. However, a \fBpcre_extra\fP block also contains other fields that can be set by the caller before the block is passed; these are described .\" HTML .\" below .\" in the section on matching a pattern. .P If studying the pattern does not produce any useful information, \fBpcre_study()\fP returns NULL. In that circumstance, if the calling program wants to pass any of the other fields to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP, it must set up its own \fBpcre_extra\fP block. .P The second argument of \fBpcre_study()\fP contains option bits. There are three options: .sp PCRE_STUDY_JIT_COMPILE PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE .sp If any of these are set, and the just-in-time compiler is available, the pattern is further compiled into machine code that executes much faster than the \fBpcre_exec()\fP interpretive matching function. If the just-in-time compiler is not available, these options are ignored. All other bits in the \fIoptions\fP argument must be zero. .P JIT compilation is a heavyweight optimization. It can take some time for patterns to be analyzed, and for one-off matches and simple patterns the benefit of faster execution might be offset by a much slower study time. Not all patterns can be optimized by the JIT compiler. For those that cannot be handled, matching automatically falls back to the \fBpcre_exec()\fP interpreter. For more details, see the .\" HREF \fBpcrejit\fP .\" documentation. .P The third argument for \fBpcre_study()\fP 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 after calling \fBpcre_study()\fP, to be sure that it has run successfully. .P When you are finished with a pattern, you can free the memory used for the study data by calling \fBpcre_free_study()\fP. This function was added to the API for release 8.20. For earlier versions, the memory could be freed with \fBpcre_free()\fP, just like the pattern itself. This will still work in cases where JIT optimization is not used, but it is advisable to change to the new function when convenient. .P This is a typical way in which \fBpcre_study\fP() is used (except that in a real application there should be tests for errors): .sp int rc; pcre *re; pcre_extra *sd; re = pcre_compile("pattern", 0, &error, &erroroffset, NULL); sd = pcre_study( re, /* result of pcre_compile() */ 0, /* no options */ &error); /* set to NULL or points to a message */ rc = pcre_exec( /* see below for details of pcre_exec() options */ re, sd, "subject", 7, 0, 0, ovector, 30); ... pcre_free_study(sd); pcre_free(re); .sp Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not mean that there are any strings of that length that match, but it does guarantee that no shorter strings match. The value is used by \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP to avoid wasting time by trying to match strings that are shorter than the lower bound. You can find out the value in a calling program via the \fBpcre_fullinfo()\fP function. .P Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at which to start matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256.) .P These two optimizations apply to both \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, and the information is also used by the JIT compiler. The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option when calling \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP, but if this is done, JIT execution is also disabled. You might want to do this if your pattern contains callouts or (*MARK) and you want to make use of these facilities in cases where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE .\" HTML .\" below. .\" . . .\" HTML .SH "LOCALE SUPPORT" .rs .sp 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. By default, higher-valued codes never match escapes such as \ew or \ed, but they can be tested with \ep if PCRE is built with Unicode character property support. Alternatively, the PCRE_UCP option can be set at compile time; this causes \ew and friends to use Unicode property support instead of built-in tables. The use of locales with Unicode is discouraged. If you are handling characters with codes greater than 128, you should either use UTF-8 and Unicode, or use locales, but not try to mix the two. .P PCRE contains an internal set of tables that are used when the final argument of \fBpcre_compile()\fP is NULL. These are sufficient for many applications. Normally, the internal tables recognize only ASCII characters. However, when PCRE is built, it is possible to cause the internal tables to be rebuilt in the default "C" locale of the local system, which may cause them to be different. .P The internal tables can always be overridden by tables supplied by the application that calls PCRE. 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. .P External tables are built by calling the \fBpcre_maketables()\fP function, which has no arguments, in the relevant locale. The result can then be passed to \fBpcre_compile()\fP or \fBpcre_exec()\fP 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: .sp setlocale(LC_CTYPE, "fr_FR"); tables = pcre_maketables(); re = pcre_compile(..., tables); .sp The locale name "fr_FR" is used on Linux and other Unix-like systems; if you are using Windows, the name for the French locale is "french". .P When \fBpcre_maketables()\fP runs, the tables are built in memory that is obtained via \fBpcre_malloc\fP. It is the caller's responsibility to ensure that the memory containing the tables remains available for as long as it is needed. .P The pointer that is passed to \fBpcre_compile()\fP is saved with the compiled pattern, and the same tables are used via this pointer by \fBpcre_study()\fP and normally also by \fBpcre_exec()\fP. Thus, by default, for any single pattern, compilation, studying and matching all happen in the same locale, but different patterns can be compiled in different locales. .P It is possible to pass a table pointer or NULL (indicating the use of the internal tables) to \fBpcre_exec()\fP. 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. . . .\" HTML .SH "INFORMATION ABOUT A PATTERN" .rs .sp .B int pcre_fullinfo(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B int \fIwhat\fP, void *\fIwhere\fP); .PP The \fBpcre_fullinfo()\fP function returns information about a compiled pattern. It replaces the \fBpcre_info()\fP function, which was removed from the library at version 8.30, after more than 10 years of obsolescence. .P The first argument for \fBpcre_fullinfo()\fP is a pointer to the compiled pattern. The second argument is the result of \fBpcre_study()\fP, 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: .sp PCRE_ERROR_NULL the argument \fIcode\fP was NULL the argument \fIwhere\fP was NULL PCRE_ERROR_BADMAGIC the "magic number" was not found PCRE_ERROR_BADENDIANNESS the pattern was compiled with different endianness PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid .sp The "magic number" is placed at the start of each compiled pattern as an simple check against passing an arbitrary memory pointer. The endianness error can occur if a compiled pattern is saved and reloaded on a different host. Here is a typical call of \fBpcre_fullinfo()\fP, to obtain the length of the compiled pattern: .sp int rc; size_t length; rc = pcre_fullinfo( re, /* result of pcre_compile() */ sd, /* result of pcre_study(), or NULL */ PCRE_INFO_SIZE, /* what is required */ &length); /* where to put the data */ .sp The possible values for the third argument are defined in \fBpcre.h\fP, and are as follows: .sp PCRE_INFO_BACKREFMAX .sp Return the number of the highest back reference in the pattern. The fourth argument should point to an \fBint\fP variable. Zero is returned if there are no back references. .sp PCRE_INFO_CAPTURECOUNT .sp Return the number of capturing subpatterns in the pattern. The fourth argument should point to an \fBint\fP variable. .sp PCRE_INFO_DEFAULT_TABLES .sp Return a pointer to the internal default character tables within PCRE. The fourth argument should point to an \fBunsigned char *\fP variable. This information call is provided for internal use by the \fBpcre_study()\fP function. External callers can cause PCRE to use its internal tables by passing a NULL table pointer. .sp PCRE_INFO_FIRSTBYTE .sp Return information about the first data unit of any matched string, for a non-anchored pattern. (The name of this option refers to the 8-bit library, where data units are bytes.) The fourth argument should point to an \fBint\fP variable. .P If there is a fixed first value, for example, the letter "c" from a pattern such as (cat|cow|coyote), its value is returned. In the 8-bit library, the value is always less than 256; in the 16-bit library the value can be up to 0xffff. .P If there is no fixed first value, and if either .sp (a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or .sp (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set (if it were set, the pattern would be anchored), .sp -1 is returned, indicating that the pattern matches only at the start of a subject string or after any newline within the string. Otherwise -2 is returned. For anchored patterns, -2 is returned. .sp PCRE_INFO_FIRSTTABLE .sp If the pattern was studied, and this resulted in the construction of a 256-bit table indicating a fixed set of values for the first data unit in any matching string, a pointer to the table is returned. Otherwise NULL is returned. The fourth argument should point to an \fBunsigned char *\fP variable. .sp PCRE_INFO_HASCRORLF .sp Return 1 if the pattern contains any explicit matches for CR or LF characters, otherwise 0. The fourth argument should point to an \fBint\fP variable. An explicit match is either a literal CR or LF character, or \er or \en. .sp PCRE_INFO_JCHANGED .sp Return 1 if the (?J) or (?-J) option setting is used in the pattern, otherwise 0. The fourth argument should point to an \fBint\fP variable. (?J) and (?-J) set and unset the local PCRE_DUPNAMES option, respectively. .sp PCRE_INFO_JIT .sp Return 1 if the pattern was studied with one of the JIT options, and just-in-time compiling was successful. The fourth argument should point to an \fBint\fP variable. A return value of 0 means that JIT support is not available in this version of PCRE, or that the pattern was not studied with a JIT option, or that the JIT compiler could not handle this particular pattern. See the .\" HREF \fBpcrejit\fP .\" documentation for details of what can and cannot be handled. .sp PCRE_INFO_JITSIZE .sp If the pattern was successfully studied with a JIT option, return the size of the JIT compiled code, otherwise return zero. The fourth argument should point to a \fBsize_t\fP variable. .sp PCRE_INFO_LASTLITERAL .sp Return the value of the rightmost literal data unit that must exist in any matched string, other than at its start, if such a value has been recorded. The fourth argument should point to an \fBint\fP variable. If there is no such value, -1 is returned. For anchored patterns, a last literal value is recorded only if it follows something of variable length. For example, for the pattern /^a\ed+z\ed+/ the returned value is "z", but for /^a\edz\ed/ the returned value is -1. .sp PCRE_INFO_MAXLOOKBEHIND .sp Return the number of characters (NB not bytes) in the longest lookbehind assertion in the pattern. Note that the simple assertions \eb and \eB require a one-character lookbehind. This information is useful when doing multi-segment matching using the partial matching facilities. .sp PCRE_INFO_MINLENGTH .sp If the pattern was studied and a minimum length for matching subject strings was computed, its value is returned. Otherwise the returned value is -1. The value is a number of characters, which in UTF-8 mode may be different from the number of bytes. The fourth argument should point to an \fBint\fP variable. A non-negative value is a lower bound to the length of any matching string. There may not be any strings of that length that do actually match, but every string that does match is at least that long. .sp PCRE_INFO_NAMECOUNT PCRE_INFO_NAMEENTRYSIZE PCRE_INFO_NAMETABLE .sp PCRE supports the use of named as well as numbered capturing parentheses. The names are just an additional way of identifying the parentheses, which still acquire numbers. Several convenience functions such as \fBpcre_get_named_substring()\fP are provided for extracting captured substrings 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 \fBpcre_exec()\fP below). To do the conversion, you need to use the name-to-number map, which is described by these three values. .P 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 of each entry; both of these return an \fBint\fP value. The entry size depends on the length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first entry of the table. This is a pointer to \fBchar\fP in the 8-bit library, where the first two bytes of each entry are the number of the capturing parenthesis, most significant byte first. In the 16-bit library, the pointer points to 16-bit data units, the first of which contains the parenthesis number. The rest of the entry is the corresponding name, zero terminated. .P The names are in alphabetical order. Duplicate names may appear if (?| is used to create multiple groups with the same number, as described in the .\" HTML .\" section on duplicate subpattern numbers .\" in the .\" HREF \fBpcrepattern\fP .\" page. Duplicate names for subpatterns with different numbers are permitted only if PCRE_DUPNAMES is set. In all cases of duplicate names, they appear in the table in the order in which they were found in the pattern. In the absence of (?| this is the order of increasing number; when (?| is used this is not necessarily the case because later subpatterns may have lower numbers. .P As a simple example of the name/number table, consider the following pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white space - including newlines - is ignored): .sp .\" JOIN (? (?(\ed\ed)?\ed\ed) - (?\ed\ed) - (?\ed\ed) ) .sp There are four named subpatterns, so the table has four entries, and each entry in the table is eight bytes long. The table is as follows, with non-printing bytes shows in hexadecimal, and undefined bytes shown as ??: .sp 00 01 d a t e 00 ?? 00 05 d a y 00 ?? ?? 00 04 m o n t h 00 00 02 y e a r 00 ?? .sp When writing code to extract data from named subpatterns using the name-to-number map, remember that the length of the entries is likely to be different for each compiled pattern. .sp PCRE_INFO_OKPARTIAL .sp Return 1 if the pattern can be used for partial matching with \fBpcre_exec()\fP, otherwise 0. The fourth argument should point to an \fBint\fP variable. From release 8.00, this always returns 1, because the restrictions that previously applied to partial matching have been lifted. The .\" HREF \fBpcrepartial\fP .\" documentation gives details of partial matching. .sp PCRE_INFO_OPTIONS .sp Return a copy of the options with which the pattern was compiled. The fourth argument should point to an \fBunsigned long int\fP variable. These option bits are those specified in the call to \fBpcre_compile()\fP, modified by any top-level option settings at the start of the pattern itself. In other words, they are the options that will be in force when matching starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, and PCRE_EXTENDED. .P A pattern is automatically anchored by PCRE if all of its top-level alternatives begin with one of the following: .sp ^ unless PCRE_MULTILINE is set \eA always \eG always .\" JOIN .* if PCRE_DOTALL is set and there are no back references to the subpattern in which .* appears .sp For such patterns, the PCRE_ANCHORED bit is set in the options returned by \fBpcre_fullinfo()\fP. .sp PCRE_INFO_SIZE .sp Return the size of the compiled pattern in bytes (for both libraries). The fourth argument should point to a \fBsize_t\fP variable. This value does not include the size of the \fBpcre\fP structure that is returned by \fBpcre_compile()\fP. The value that is passed as the argument to \fBpcre_malloc()\fP when \fBpcre_compile()\fP is getting memory in which to place the compiled data is the value returned by this option plus the size of the \fBpcre\fP structure. Studying a compiled pattern, with or without JIT, does not alter the value returned by this option. .sp PCRE_INFO_STUDYSIZE .sp Return the size in bytes of the data block pointed to by the \fIstudy_data\fP field in a \fBpcre_extra\fP block. If \fBpcre_extra\fP is NULL, or there is no study data, zero is returned. The fourth argument should point to a \fBsize_t\fP variable. The \fIstudy_data\fP field is set by \fBpcre_study()\fP to record information that will speed up matching (see the section entitled .\" HTML .\" "Studying a pattern" .\" above). The format of the \fIstudy_data\fP block is private, but its length is made available via this option so that it can be saved and restored (see the .\" HREF \fBpcreprecompile\fP .\" documentation for details). . . .SH "REFERENCE COUNTS" .rs .sp .B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); .PP The \fBpcre_refcount()\fP function is used to maintain a reference count in the data block that contains a compiled pattern. It is provided for the benefit of applications that operate in an object-oriented manner, where different parts of the application may be using the same compiled pattern, but you want to free the block when they are all done. .P When a pattern is compiled, the reference count field is initialized to zero. It is changed only by calling this function, whose action is to add the \fIadjust\fP value (which may be positive or negative) to it. The yield of the function is the new value. However, the value of the count is constrained to lie between 0 and 65535, inclusive. If the new value is outside these limits, it is forced to the appropriate limit value. .P Except when it is zero, the reference count is not correctly preserved if a pattern is compiled on one host and then transferred to a host whose byte-order is different. (This seems a highly unlikely scenario.) . . .SH "MATCHING A PATTERN: THE TRADITIONAL FUNCTION" .rs .sp .B int pcre_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); .P The function \fBpcre_exec()\fP is called to match a subject string against a compiled pattern, which is passed in the \fIcode\fP argument. If the pattern was studied, the result of the study should be passed in the \fIextra\fP argument. You can call \fBpcre_exec()\fP with the same \fIcode\fP and \fIextra\fP arguments as many times as you like, in order to match different subject strings with the same pattern. .P This function is the main matching facility of the library, and it operates in a Perl-like manner. For specialist use there is also an alternative matching function, which is described .\" HTML .\" below .\" in the section about the \fBpcre_dfa_exec()\fP function. .P In most applications, the pattern will have been compiled (and optionally studied) in the same process that calls \fBpcre_exec()\fP. However, it is possible to save compiled patterns and study data, and then use them later in different processes, possibly even on different hosts. For a discussion about this, see the .\" HREF \fBpcreprecompile\fP .\" documentation. .P Here is an example of a simple call to \fBpcre_exec()\fP: .sp int rc; int ovector[30]; rc = pcre_exec( re, /* result of pcre_compile() */ NULL, /* we didn't study the pattern */ "some string", /* the subject string */ 11, /* the length of the subject string */ 0, /* start at offset 0 in the subject */ 0, /* default options */ ovector, /* vector of integers for substring information */ 30); /* number of elements (NOT size in bytes) */ . . .\" HTML .SS "Extra data for \fBpcre_exec()\fR" .rs .sp If the \fIextra\fP argument is not NULL, it must point to a \fBpcre_extra\fP data block. The \fBpcre_study()\fP function returns such a block (when it doesn't return NULL), but you can also create one for yourself, and pass additional information in it. The \fBpcre_extra\fP block contains the following fields (not necessarily in this order): .sp unsigned long int \fIflags\fP; void *\fIstudy_data\fP; void *\fIexecutable_jit\fP; unsigned long int \fImatch_limit\fP; unsigned long int \fImatch_limit_recursion\fP; void *\fIcallout_data\fP; const unsigned char *\fItables\fP; unsigned char **\fImark\fP; .sp In the 16-bit version of this structure, the \fImark\fP field has type "PCRE_UCHAR16 **". .P The \fIflags\fP field is used to specify which of the other fields are set. The flag bits are: .sp PCRE_EXTRA_CALLOUT_DATA PCRE_EXTRA_EXECUTABLE_JIT PCRE_EXTRA_MARK PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_MATCH_LIMIT_RECURSION PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_TABLES .sp Other flag bits should be set to zero. The \fIstudy_data\fP field and sometimes the \fIexecutable_jit\fP field are set in the \fBpcre_extra\fP block that is returned by \fBpcre_study()\fP, together with the appropriate flag bits. You should not set these yourself, but you may add to the block by setting other fields and their corresponding flag bits. .P The \fImatch_limit\fP field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats. .P Internally, \fBpcre_exec()\fP uses a function called \fBmatch()\fP, which it calls repeatedly (sometimes recursively). The limit set by \fImatch_limit\fP is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. For patterns that are not anchored, the count restarts from zero for each position in the subject string. .P When \fBpcre_exec()\fP is called with a pattern that was successfully studied with a JIT option, the way that the matching is executed is entirely different. However, there is still the possibility of runaway matching that goes on for a very long time, and so the \fImatch_limit\fP value is also used in this case (but in a different way) to limit how long the matching can continue. .P The default value for the limit can be set when PCRE is built; the default default is 10 million, which handles all but the most extreme cases. You can override the default by suppling \fBpcre_exec()\fP with a \fBpcre_extra\fP block in which \fImatch_limit\fP is set, and PCRE_EXTRA_MATCH_LIMIT is set in the \fIflags\fP field. If the limit is exceeded, \fBpcre_exec()\fP returns PCRE_ERROR_MATCHLIMIT. .P The \fImatch_limit_recursion\fP field is similar to \fImatch_limit\fP, but instead of limiting the total number of times that \fBmatch()\fP is called, it limits the depth of recursion. The recursion depth is a smaller number than the total number of calls, because not all calls to \fBmatch()\fP are recursive. This limit is of use only if it is set smaller than \fImatch_limit\fP. .P Limiting the recursion depth limits the amount of machine stack that can be used, or, when PCRE has been compiled to use memory on the heap instead of the stack, the amount of heap memory that can be used. This limit is not relevant, and is ignored, when matching is done using JIT compiled code. .P The default value for \fImatch_limit_recursion\fP can be set when PCRE is built; the default default is the same value as the default for \fImatch_limit\fP. You can override the default by suppling \fBpcre_exec()\fP with a \fBpcre_extra\fP block in which \fImatch_limit_recursion\fP is set, and PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the \fIflags\fP field. If the limit is exceeded, \fBpcre_exec()\fP returns PCRE_ERROR_RECURSIONLIMIT. .P The \fIcallout_data\fP field is used in conjunction with the "callout" feature, and is described in the .\" HREF \fBpcrecallout\fP .\" documentation. .P The \fItables\fP field is used to pass a character tables pointer to \fBpcre_exec()\fP; this overrides the value that is stored with the compiled pattern. A non-NULL value is stored with the compiled pattern only if custom tables were supplied to \fBpcre_compile()\fP via its \fItableptr\fP argument. If NULL is passed to \fBpcre_exec()\fP using this mechanism, it forces PCRE's internal tables to be used. This facility is helpful when re-using patterns that have been saved after compiling with an external set of tables, because the external tables might be at a different address when \fBpcre_exec()\fP is called. See the .\" HREF \fBpcreprecompile\fP .\" documentation for a discussion of saving compiled patterns for later use. .P If PCRE_EXTRA_MARK is set in the \fIflags\fP field, the \fImark\fP field must be set to point to a suitable variable. If the pattern contains any backtracking control verbs such as (*MARK:NAME), and the execution ends up with a name to pass back, a pointer to the name string (zero terminated) is placed in the variable pointed to by the \fImark\fP field. The names are within the compiled pattern; if you wish to retain such a name you must copy it before freeing the memory of a compiled pattern. If there is no name to pass back, the variable pointed to by the \fImark\fP field is set to NULL. For details of the backtracking control verbs, see the section entitled .\" HTML .\" "Backtracking control" .\" in the .\" HREF \fBpcrepattern\fP .\" documentation. . . .\" HTML .SS "Option bits for \fBpcre_exec()\fP" .rs .sp The unused bits of the \fIoptions\fP argument for \fBpcre_exec()\fP must be zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_\fIxxx\fP, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. .P If the pattern was successfully studied with one of the just-in-time (JIT) compile options, the only supported options for JIT execution are PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an unsupported option is used, JIT execution is disabled and the normal interpretive code in \fBpcre_exec()\fP is run. .sp PCRE_ANCHORED .sp The PCRE_ANCHORED option limits \fBpcre_exec()\fP 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. .sp PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE .sp These options (which are mutually exclusive) control what the \eR escape sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. These options override the choice that was made or defaulted when the pattern was compiled. .sp PCRE_NEWLINE_CR PCRE_NEWLINE_LF PCRE_NEWLINE_CRLF PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY .sp These options override the newline definition that was chosen or defaulted when the pattern was compiled. For details, see the description of \fBpcre_compile()\fP above. During matching, the newline choice affects the behaviour of the dot, circumflex, and dollar metacharacters. It may also alter the way the match position is advanced after a match failure for an unanchored pattern. .P When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is set, and a match attempt for an unanchored pattern fails when the current position is at a CRLF sequence, and the pattern contains no explicit matches for CR or LF characters, the match position is advanced by two characters instead of one, in other words, to after the CRLF. .P The above rule is a compromise that makes the most common cases work as expected. For example, if the pattern is .+A (and the PCRE_DOTALL option is not set), it does not match the string "\er\enA" because, after failing at the start, it skips both the CR and the LF before retrying. However, the pattern [\er\en]A does match that string, because it contains an explicit CR or LF reference, and so advances only by one character after the first failure. .P An explicit match for CR of LF is either a literal appearance of one of those characters, or one of the \er or \en escape sequences. Implicit matches such as [^X] do not count, nor does \es (which includes CR and LF in the characters that it matches). .P Notwithstanding the above, anomalous effects may still occur when CRLF is a valid newline sequence and explicit \er or \en escapes appear in the pattern. .sp PCRE_NOTBOL .sp This option specifies that first character of the subject string is not the beginning of a line, so the circumflex metacharacter should not match before it. Setting this without PCRE_MULTILINE (at compile time) causes circumflex never to match. This option affects only the behaviour of the circumflex metacharacter. It does not affect \eA. .sp PCRE_NOTEOL .sp This option specifies that the end of the subject string is not the end of a line, so the dollar metacharacter should not match it nor (except in multiline mode) a newline immediately before it. Setting this without PCRE_MULTILINE (at compile time) causes dollar never to match. This option affects only the behaviour of the dollar metacharacter. It does not affect \eZ or \ez. .sp PCRE_NOTEMPTY .sp An empty string is not considered to be a valid match if this option is set. If there are alternatives in the pattern, they are tried. If all the alternatives match the empty string, the entire match fails. For example, if the pattern .sp a?b? .sp is applied to a string not beginning with "a" or "b", it matches an empty string at the start of the subject. With PCRE_NOTEMPTY set, this match is not valid, so PCRE searches further into the string for occurrences of "a" or "b". .sp PCRE_NOTEMPTY_ATSTART .sp This is like PCRE_NOTEMPTY, except that an empty string match that is not at the start of the subject is permitted. If the pattern is anchored, such a match can occur only if the pattern contains \eK. .P Perl has no direct equivalent of PCRE_NOTEMPTY or PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern match of the empty string within its \fBsplit()\fP function, and when using the /g modifier. It is possible to emulate Perl's behaviour after matching a null string by first trying the match again at the same offset with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that fails, by advancing the starting offset (see below) and trying an ordinary match again. There is some code that demonstrates how to do this in the .\" HREF \fBpcredemo\fP .\" sample program. In the most general case, you have to check to see if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. .sp PCRE_NO_START_OPTIMIZE .sp There are a number of optimizations that \fBpcre_exec()\fP uses at the start of a match, in order to speed up the process. For example, if it is known that an unanchored match must start with a specific character, it searches the subject for that character, and fails immediately if it cannot find it, without actually running the main matching function. This means that a special item such as (*COMMIT) at the start of a pattern is not considered until after a suitable starting point for the match has been found. When callouts or (*MARK) items are in use, these "start-up" optimizations can cause them to be skipped if the pattern is never actually used. The start-up optimizations are in effect a pre-scan of the subject that takes place before the pattern is run. .P The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly causing performance to suffer, but ensuring that in cases where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching is always done using interpretively. .P Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern .sp (*COMMIT)ABC .sp When this is compiled, PCRE records the fact that a match must start with the character "A". Suppose the subject string is "DEFABC". The start-up optimization scans along the subject, finds "A" and runs the first match attempt from there. The (*COMMIT) item means that the pattern must match the current starting position, which in this case, it does. However, if the same match is run with PCRE_NO_START_OPTIMIZE set, the initial scan along the subject string does not happen. The first match attempt is run starting from "D" and when this fails, (*COMMIT) prevents any further matches being tried, so the overall result is "no match". If the pattern is studied, more start-up optimizations may be used. For example, a minimum length for the subject may be recorded. Consider the pattern .sp (*MARK:A)(X|Y) .sp The minimum length for a match is one character. If the subject is "ABC", there will be attempts to match "ABC", "BC", "C", and then finally an empty string. If the pattern is studied, the final attempt does not take place, because PCRE knows that the subject is too short, and so the (*MARK) is never encountered. In this case, studying the pattern does not affect the overall match result, which is still "no match", but it does affect the auxiliary information that is returned. .sp PCRE_NO_UTF8_CHECK .sp When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8 string is automatically checked when \fBpcre_exec()\fP is subsequently called. The entire string is checked before any other processing takes place. The value of \fIstartoffset\fP is also checked to ensure that it points to the start of a UTF-8 character. There is a discussion about the .\" HTML .\" validity of UTF-8 strings .\" in the .\" HREF \fBpcreunicode\fP .\" page. If an invalid sequence of bytes is found, \fBpcre_exec()\fP returns the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In both cases, information about the precise nature of the error may also be returned (see the descriptions of these errors in the section entitled \fIError return values from\fP \fBpcre_exec()\fP .\" HTML .\" below). .\" If \fIstartoffset\fP contains a value that does not point to the start of a UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. .P If you already know that your subject is valid, and you want to skip these checks for performance reasons, you can set the PCRE_NO_UTF8_CHECK option when calling \fBpcre_exec()\fP. You might want to do this for the second and subsequent calls to \fBpcre_exec()\fP if you are making repeated calls to find all the matches in a single subject string. However, you should be sure that the value of \fIstartoffset\fP points to the start of a character (or the end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a subject or an invalid value of \fIstartoffset\fP is undefined. Your program may crash. .sp PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT .sp These options turn on the partial matching feature. For backwards compatibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial match occurs if the end of the subject string is reached successfully, but there are not enough subject characters to complete the match. If this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set, matching continues by testing any remaining alternatives. Only if no complete match can be found is PCRE_ERROR_PARTIAL returned instead of PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the caller is prepared to handle a partial match, but only if no complete match can be found. .P If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this case, if a partial match is found, \fBpcre_exec()\fP immediately returns PCRE_ERROR_PARTIAL, without considering any other alternatives. In other words, when PCRE_PARTIAL_HARD is set, a partial match is considered to be more important that an alternative complete match. .P In both cases, the portion of the string that was inspected when the partial match was found is set as the first matching string. There is a more detailed discussion of partial and multi-segment matching, with examples, in the .\" HREF \fBpcrepartial\fP .\" documentation. . . .SS "The string to be matched by \fBpcre_exec()\fP" .rs .sp The subject string is passed to \fBpcre_exec()\fP as a pointer in \fIsubject\fP, a length in bytes in \fIlength\fP, and a starting byte offset in \fIstartoffset\fP. If this is negative or greater than the length of the subject, \fBpcre_exec()\fP returns PCRE_ERROR_BADOFFSET. When the starting offset is zero, the search for a match starts at the beginning of the subject, and this is by far the most common case. In UTF-8 mode, the byte offset must point to the start of a UTF-8 character (or the end of the subject). Unlike the pattern string, the subject may contain binary zero bytes. .P A non-zero starting offset is useful when searching for another match in the same subject by calling \fBpcre_exec()\fP again after a previous success. Setting \fIstartoffset\fP differs from just passing over a shortened string and setting PCRE_NOTBOL in the case of a pattern that begins with any kind of lookbehind. For example, consider the pattern .sp \eBiss\eB .sp which finds occurrences of "iss" in the middle of words. (\eB matches only if the current position in the subject is not a word boundary.) When applied to the string "Mississipi" the first call to \fBpcre_exec()\fP finds the first occurrence. If \fBpcre_exec()\fP is called again with just the remainder of the subject, namely "issipi", it does not match, because \eB is always false at the start of the subject, which is deemed to be a word boundary. However, if \fBpcre_exec()\fP is passed the entire string again, but with \fIstartoffset\fP set to 4, it finds the second occurrence of "iss" because it is able to look behind the starting point to discover that it is preceded by a letter. .P Finding all the matches in a subject is tricky when the pattern can match an empty string. It is possible to emulate Perl's /g behaviour by first trying the match again at the same offset, with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that fails, advancing the starting offset and trying an ordinary match again. There is some code that demonstrates how to do this in the .\" HREF \fBpcredemo\fP .\" sample program. In the most general case, you have to check to see if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. .P If a non-zero starting offset is passed when the pattern is anchored, one attempt to match at the given offset is made. This can only succeed if the pattern does not require the match to be at the start of the subject. . . .SS "How \fBpcre_exec()\fP returns captured substrings" .rs .sp In general, a pattern matches a certain portion of the subject, and in addition, further substrings from the subject may be picked out by parts of the pattern. Following the usage in Jeffrey Friedl's book, this is called "capturing" in what follows, and the phrase "capturing subpattern" is used for a fragment of a pattern that picks out a substring. PCRE supports several other kinds of parenthesized subpattern that do not cause substrings to be captured. .P Captured substrings are returned to the caller via a vector of integers whose address is passed in \fIovector\fP. The number of elements in the vector is passed in \fIovecsize\fP, which must be a non-negative number. \fBNote\fP: this argument is NOT the size of \fIovector\fP in bytes. .P The first two-thirds of the vector is used to pass back captured substrings, each substring using a pair of integers. The remaining third of the vector is used as workspace by \fBpcre_exec()\fP while matching capturing subpatterns, and is not available for passing back information. The number passed in \fIovecsize\fP should always be a multiple of three. If it is not, it is rounded down. .P When a match is successful, information about captured substrings is returned in pairs of integers, starting at the beginning of \fIovector\fP, and continuing up to two-thirds of its length at the most. The first element of each pair is set to the byte offset of the first character in a substring, and the second is set to the byte offset of the first character after the end of a substring. \fBNote\fP: these values are always byte offsets, even in UTF-8 mode. They are not character counts. .P The first pair of integers, \fIovector[0]\fP and \fIovector[1]\fP, identify the portion of the subject string matched by the entire pattern. The next pair is used for the first capturing subpattern, and so on. The value returned by \fBpcre_exec()\fP 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. .P If a capturing subpattern is matched repeatedly, it is the last portion of the string that it matched that is returned. .P 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. If neither the actual string matched nor any captured substrings are of interest, \fBpcre_exec()\fP may be called with \fIovector\fP passed as NULL and \fIovecsize\fP as zero. However, if the pattern contains back references and the \fIovector\fP 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 \fIovector\fP of reasonable size. .P There are some cases where zero is returned (indicating vector overflow) when in fact the vector is exactly the right size for the final match. For example, consider the pattern .sp (a)(?:(b)c|bd) .sp If a vector of 6 elements (allowing for only 1 captured substring) is given with subject string "abd", \fBpcre_exec()\fP will try to set the second captured string, thereby recording a vector overflow, before failing to match "c" and backing up to try the second alternative. The zero return, however, does correctly indicate that the maximum number of slots (namely 2) have been filled. In similar cases where there is temporary overflow, but the final number of used slots is actually less than the maximum, a non-zero value is returned. .P The \fBpcre_fullinfo()\fP function can be used to find out how many capturing subpatterns there are in a compiled pattern. The smallest size for \fIovector\fP that will allow for \fIn\fP captured substrings, in addition to the offsets of the substring matched by the whole pattern, is (\fIn\fP+1)*3. .P It is possible for capturing subpattern number \fIn+1\fP to match some part of the subject when subpattern \fIn\fP 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 corresponding to unused subpatterns are set to -1. .P 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, and the offsets for for the second and third capturing subpatterns (assuming the vector is large enough, of course) are set to -1. .P \fBNote\fP: Elements in the first two-thirds of \fIovector\fP that do not correspond to capturing parentheses in the pattern are never changed. That is, if a pattern contains \fIn\fP capturing parentheses, no more than \fIovector[0]\fP to \fIovector[2n+1]\fP are set by \fBpcre_exec()\fP. The other elements (in the first two-thirds) retain whatever values they previously had. .P Some convenience functions are provided for extracting the captured substrings as separate strings. These are described below. . . .\" HTML .SS "Error return values from \fBpcre_exec()\fP" .rs .sp If \fBpcre_exec()\fP fails, it returns a negative number. The following are defined in the header file: .sp PCRE_ERROR_NOMATCH (-1) .sp The subject string did not match the pattern. .sp PCRE_ERROR_NULL (-2) .sp Either \fIcode\fP or \fIsubject\fP was passed as NULL, or \fIovector\fP was NULL and \fIovecsize\fP was not zero. .sp PCRE_ERROR_BADOPTION (-3) .sp An unrecognized bit was set in the \fIoptions\fP argument. .sp PCRE_ERROR_BADMAGIC (-4) .sp 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 gives when the magic number is not present. .sp PCRE_ERROR_UNKNOWN_OPCODE (-5) .sp 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 overwriting of the compiled pattern. .sp PCRE_ERROR_NOMEMORY (-6) .sp If a pattern contains back references, but the \fIovector\fP that is passed to \fBpcre_exec()\fP 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 \fBpcre_malloc()\fP fails, this error is given. The memory is automatically freed at the end of matching. .P This error is also given if \fBpcre_stack_malloc()\fP fails in \fBpcre_exec()\fP. This can happen only when PCRE has been compiled with \fB--disable-stack-for-recursion\fP. .sp PCRE_ERROR_NOSUBSTRING (-7) .sp This error is used by the \fBpcre_copy_substring()\fP, \fBpcre_get_substring()\fP, and \fBpcre_get_substring_list()\fP functions (see below). It is never returned by \fBpcre_exec()\fP. .sp PCRE_ERROR_MATCHLIMIT (-8) .sp The backtracking limit, as specified by the \fImatch_limit\fP field in a \fBpcre_extra\fP structure (or defaulted) was reached. See the description above. .sp PCRE_ERROR_CALLOUT (-9) .sp This error is never generated by \fBpcre_exec()\fP itself. It is provided for use by callout functions that want to yield a distinctive error code. See the .\" HREF \fBpcrecallout\fP .\" documentation for details. .sp PCRE_ERROR_BADUTF8 (-10) .sp A string that contains an invalid UTF-8 byte sequence was passed as a subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector (\fIovecsize\fP) is at least 2, the byte offset to the start of the the invalid UTF-8 character is placed in the first element, and a reason code is placed in the second element. The reason codes are listed in the .\" HTML .\" following section. .\" For backward compatibility, if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 character at the end of the subject (reason codes 1 to 5), PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8. .sp PCRE_ERROR_BADUTF8_OFFSET (-11) .sp The UTF-8 byte sequence that was passed as a subject was checked and found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the value of \fIstartoffset\fP did not point to the beginning of a UTF-8 character or the end of the subject. .sp PCRE_ERROR_PARTIAL (-12) .sp The subject string did not match, but it did match partially. See the .\" HREF \fBpcrepartial\fP .\" documentation for details of partial matching. .sp PCRE_ERROR_BADPARTIAL (-13) .sp This code is no longer in use. It was formerly returned when the PCRE_PARTIAL option was used with a compiled pattern containing items that were not supported for partial matching. From release 8.00 onwards, there are no restrictions on partial matching. .sp PCRE_ERROR_INTERNAL (-14) .sp An unexpected internal error has occurred. This error could be caused by a bug in PCRE or by overwriting of the compiled pattern. .sp PCRE_ERROR_BADCOUNT (-15) .sp This error is given if the value of the \fIovecsize\fP argument is negative. .sp PCRE_ERROR_RECURSIONLIMIT (-21) .sp The internal recursion limit, as specified by the \fImatch_limit_recursion\fP field in a \fBpcre_extra\fP structure (or defaulted) was reached. See the description above. .sp PCRE_ERROR_BADNEWLINE (-23) .sp An invalid combination of PCRE_NEWLINE_\fIxxx\fP options was given. .sp PCRE_ERROR_BADOFFSET (-24) .sp The value of \fIstartoffset\fP was negative or greater than the length of the subject, that is, the value in \fIlength\fP. .sp PCRE_ERROR_SHORTUTF8 (-25) .sp This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set. Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but this special error code for PCRE_PARTIAL_HARD precedes the implementation of returned information; it is retained for backwards compatibility. .sp PCRE_ERROR_RECURSELOOP (-26) .sp This error is returned when \fBpcre_exec()\fP detects a recursion loop within the pattern. Specifically, it means that either the whole pattern or a subpattern has been called recursively for the second time at the same position in the subject string. Some simple patterns that might do this are detected and faulted at compile time, but more complicated cases, in particular mutual recursions between two different subpatterns, cannot be detected until run time. .sp PCRE_ERROR_JIT_STACKLIMIT (-27) .sp This error is returned when a pattern that was successfully studied using a JIT compile option is being matched, but the memory available for the just-in-time processing stack is not large enough. See the .\" HREF \fBpcrejit\fP .\" documentation for more details. .sp PCRE_ERROR_BADMODE (-28) .sp This error is given if a pattern that was compiled by the 8-bit library is passed to a 16-bit library function, or vice versa. .sp PCRE_ERROR_BADENDIANNESS (-29) .sp This error is given if a pattern that was compiled and saved is reloaded on a host with different endianness. The utility function \fBpcre_pattern_to_host_byte_order()\fP can be used to convert such a pattern so that it runs on the new host. .P Error numbers -16 to -20, -22, and -30 are not used by \fBpcre_exec()\fP. . . .\" HTML .SS "Reason codes for invalid UTF-8 strings" .rs .sp This section applies only to the 8-bit library. The corresponding information for the 16-bit library is given in the .\" HREF \fBpcre16\fP .\" page. .P When \fBpcre_exec()\fP returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORTUTF8, and the size of the output vector (\fIovecsize\fP) is at least 2, the offset of the start of the invalid UTF-8 character is placed in the first output vector element (\fIovector[0]\fP) and a reason code is placed in the second element (\fIovector[1]\fP). The reason codes are given names in the \fBpcre.h\fP header file: .sp PCRE_UTF8_ERR1 PCRE_UTF8_ERR2 PCRE_UTF8_ERR3 PCRE_UTF8_ERR4 PCRE_UTF8_ERR5 .sp The string ends with a truncated UTF-8 character; the code specifies how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 characters to be no longer than 4 bytes, the encoding scheme (originally defined by RFC 2279) allows for up to 6 bytes, and this is checked first; hence the possibility of 4 or 5 missing bytes. .sp PCRE_UTF8_ERR6 PCRE_UTF8_ERR7 PCRE_UTF8_ERR8 PCRE_UTF8_ERR9 PCRE_UTF8_ERR10 .sp The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of the character do not have the binary value 0b10 (that is, either the most significant bit is 0, or the next bit is 1). .sp PCRE_UTF8_ERR11 PCRE_UTF8_ERR12 .sp A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long; these code points are excluded by RFC 3629. .sp PCRE_UTF8_ERR13 .sp A 4-byte character has a value greater than 0x10fff; these code points are excluded by RFC 3629. .sp PCRE_UTF8_ERR14 .sp A 3-byte character has a value in the range 0xd800 to 0xdfff; this range of code points are reserved by RFC 3629 for use with UTF-16, and so are excluded from UTF-8. .sp PCRE_UTF8_ERR15 PCRE_UTF8_ERR16 PCRE_UTF8_ERR17 PCRE_UTF8_ERR18 PCRE_UTF8_ERR19 .sp A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes for a value that can be represented by fewer bytes, which is invalid. For example, the two bytes 0xc0, 0xae give the value 0x2e, whose correct coding uses just one byte. .sp PCRE_UTF8_ERR20 .sp The two most significant bits of the first byte of a character have the binary value 0b10 (that is, the most significant bit is 1 and the second is 0). Such a byte can only validly occur as the second or subsequent byte of a multi-byte character. .sp PCRE_UTF8_ERR21 .sp The first byte of a character has the value 0xfe or 0xff. These values can never occur in a valid UTF-8 string. . . .SH "EXTRACTING CAPTURED SUBSTRINGS BY NUMBER" .rs .sp .B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, .ti +5n .B int \fIbuffersize\fP); .PP .B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, .ti +5n .B const char **\fIstringptr\fP); .PP .B int pcre_get_substring_list(const char *\fIsubject\fP, .ti +5n .B int *\fIovector\fP, int \fIstringcount\fP, "const char ***\fIlistptr\fP);" .PP Captured substrings can be accessed directly by using the offsets returned by \fBpcre_exec()\fP in \fIovector\fP. For convenience, the functions \fBpcre_copy_substring()\fP, \fBpcre_get_substring()\fP, and \fBpcre_get_substring_list()\fP 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. .P 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 \fBpcre_copy_substring()\fP and \fBpcre_get_substring()\fP. Unfortunately, the interface to \fBpcre_get_substring_list()\fP is not adequate for handling strings containing binary zeros, because the end of the final string is not independently indicated. .P The first three arguments are the same for all three of these functions: \fIsubject\fP is the subject string that has just been successfully matched, \fIovector\fP is a pointer to the vector of integer offsets that was passed to \fBpcre_exec()\fP, and \fIstringcount\fP is the number of substrings that were captured by the match, including the substring that matched the entire regular expression. This is the value returned by \fBpcre_exec()\fP if it is greater than zero. If \fBpcre_exec()\fP returned zero, indicating that it ran out of space in \fIovector\fP, the value passed as \fIstringcount\fP should be the number of elements in the vector divided by three. .P The functions \fBpcre_copy_substring()\fP and \fBpcre_get_substring()\fP extract a single substring, whose number is given as \fIstringnumber\fP. A value of zero extracts the substring that matched the entire pattern, whereas higher values extract the captured substrings. For \fBpcre_copy_substring()\fP, the string is placed in \fIbuffer\fP, whose length is given by \fIbuffersize\fP, while for \fBpcre_get_substring()\fP a new block of memory is obtained via \fBpcre_malloc\fP, and its address is returned via \fIstringptr\fP. The yield of the function is the length of the string, not including the terminating zero, or one of these error codes: .sp PCRE_ERROR_NOMEMORY (-6) .sp The buffer was too small for \fBpcre_copy_substring()\fP, or the attempt to get memory failed for \fBpcre_get_substring()\fP. .sp PCRE_ERROR_NOSUBSTRING (-7) .sp There is no substring whose number is \fIstringnumber\fP. .P The \fBpcre_get_substring_list()\fP function extracts all available substrings and builds a list of pointers to them. All this is done in a single block of memory that is obtained via \fBpcre_malloc\fP. The address of the memory block is returned via \fIlistptr\fP, 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 the error code .sp PCRE_ERROR_NOMEMORY (-6) .sp if the attempt to get the memory block failed. .P When any of these functions encounter a substring that is unset, which can happen when capturing subpattern number \fIn+1\fP matches some part of the subject, but subpattern \fIn\fP has not been used at all, they return an empty string. This can be distinguished from a genuine zero-length substring by inspecting the appropriate offset in \fIovector\fP, which is negative for unset substrings. .P The two convenience functions \fBpcre_free_substring()\fP and \fBpcre_free_substring_list()\fP can be used to free the memory returned by a previous call of \fBpcre_get_substring()\fP or \fBpcre_get_substring_list()\fP, respectively. They do nothing more than call the function pointed to by \fBpcre_free\fP, which of course could be called directly from a C program. However, PCRE is used in some situations where it is linked via a special interface to another programming language that cannot use \fBpcre_free\fP directly; it is for these cases that the functions are provided. . . .SH "EXTRACTING CAPTURED SUBSTRINGS BY NAME" .rs .sp .B int pcre_get_stringnumber(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP); .PP .B int pcre_copy_named_substring(const pcre *\fIcode\fP, .ti +5n .B const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B char *\fIbuffer\fP, int \fIbuffersize\fP); .PP .B int pcre_get_named_substring(const pcre *\fIcode\fP, .ti +5n .B const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B const char **\fIstringptr\fP); .PP To extract a substring by name, you first have to find associated number. For example, for this pattern .sp (a+)b(?\ed+)... .sp 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 \fBpcre_get_stringnumber()\fP. 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. .P Given the number, you can extract the substring directly, or use one of the functions described in the previous section. For convenience, there are also two functions that do the whole job. .P Most of the arguments of \fBpcre_copy_named_substring()\fP and \fBpcre_get_named_substring()\fP are the same as those for the similarly named functions that extract by number. As these are described in the previous section, they are not re-described here. There are just two differences: .P First, instead of a substring number, a substring name is given. Second, there is an extra argument, given at the start, which is a pointer to the compiled pattern. This is needed in order to gain access to the name-to-number translation table. .P These functions call \fBpcre_get_stringnumber()\fP, and if it succeeds, they then call \fBpcre_copy_substring()\fP or \fBpcre_get_substring()\fP, as appropriate. \fBNOTE:\fP If PCRE_DUPNAMES is set and there are duplicate names, the behaviour may not be what you want (see the next section). .P \fBWarning:\fP If the pattern uses the (?| feature to set up multiple subpatterns with the same number, as described in the .\" HTML .\" section on duplicate subpattern numbers .\" in the .\" HREF \fBpcrepattern\fP .\" page, you cannot use names to distinguish the different subpatterns, because names are not included in the compiled code. The matching process uses only numbers. For this reason, the use of different names for subpatterns of the same number causes an error at compile time. . . .SH "DUPLICATE SUBPATTERN NAMES" .rs .sp .B int pcre_get_stringtable_entries(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP); .PP When a pattern is compiled with the PCRE_DUPNAMES option, names for subpatterns are not required to be unique. (Duplicate names are always allowed for subpatterns with the same number, created by using the (?| feature. Indeed, if such subpatterns are named, they are required to use the same names.) .P 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 .\" HREF \fBpcrepattern\fP .\" documentation. .P When duplicates are present, \fBpcre_copy_named_substring()\fP and \fBpcre_get_named_substring()\fP return the first substring corresponding to the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING (-7) is returned; no data is returned. The \fBpcre_get_stringnumber()\fP function returns one of the numbers that are associated with the name, but it is not defined which it is. .P If you want to get full details of all captured substrings for a given name, you must use the \fBpcre_get_stringtable_entries()\fP 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 (-7) if there are none. The format of the table is described above in the section entitled \fIInformation about a pattern\fP .\" HTML .\" above. .\" Given all the relevant entries for the name, you can extract each of their numbers, and hence the captured data, if any. . . .SH "FINDING ALL POSSIBLE MATCHES" .rs .sp 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 of the callout facility, which is described in the .\" HREF \fBpcrecallout\fP .\" documentation. .P What you have to do is to insert a callout right at the end of the pattern. When your callout function is called, extract and save the current matched substring. Then return 1, which forces \fBpcre_exec()\fP to backtrack and try other alternatives. Ultimately, when it runs out of matches, \fBpcre_exec()\fP will yield PCRE_ERROR_NOMATCH. . . .SH "OBTAINING AN ESTIMATE OF STACK USAGE" .rs .sp Matching certain patterns using \fBpcre_exec()\fP can use a lot of process stack, which in certain environments can be rather limited in size. Some users find it helpful to have an estimate of the amount of stack that is used by \fBpcre_exec()\fP, to help them set recursion limits, as described in the .\" HREF \fBpcrestack\fP .\" documentation. The estimate that is output by \fBpcretest\fP when called with the \fB-m\fP and \fB-C\fP options is obtained by calling \fBpcre_exec\fP with the values NULL, NULL, NULL, -999, and -999 for its first five arguments. .P Normally, if its first argument is NULL, \fBpcre_exec()\fP immediately returns the negative error code PCRE_ERROR_NULL, but with this special combination of arguments, it returns instead a negative number whose absolute value is the approximate stack frame size in bytes. (A negative number is used so that it is clear that no match has happened.) The value is approximate because in some cases, recursive calls to \fBpcre_exec()\fP occur when there are one or two additional variables on the stack. .P If PCRE has been compiled to use the heap instead of the stack for recursion, the value returned is the size of each block that is obtained from the heap. . . .\" HTML .SH "MATCHING A PATTERN: THE ALTERNATIVE FUNCTION" .rs .sp .B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, .ti +5n .B int *\fIworkspace\fP, int \fIwscount\fP); .P The function \fBpcre_dfa_exec()\fP is called to match a subject string against a compiled pattern, using a matching algorithm that scans the subject string just once, and does not backtrack. This has different characteristics to the normal algorithm, and is not compatible 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, and a list of features that \fBpcre_dfa_exec()\fP does not support, see the .\" HREF \fBpcrematching\fP .\" documentation. .P The arguments for the \fBpcre_dfa_exec()\fP function are the same as for \fBpcre_exec()\fP, plus two extras. The \fIovector\fP argument is used in a different way, and this is described below. The other common arguments are used in the same way as for \fBpcre_exec()\fP, so their description is not repeated here. .P 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 potential matches. .P Here is an example of a simple call to \fBpcre_dfa_exec()\fP: .sp int rc; int ovector[10]; int wspace[20]; rc = pcre_dfa_exec( re, /* result of pcre_compile() */ NULL, /* we didn't study the pattern */ "some string", /* the subject string */ 11, /* the length of the subject string */ 0, /* start at offset 0 in the subject */ 0, /* default options */ ovector, /* vector of integers for substring information */ 10, /* number of elements (NOT size in bytes) */ wspace, /* working space vector */ 20); /* number of elements (NOT size in bytes) */ . .SS "Option bits for \fBpcre_dfa_exec()\fP" .rs .sp The unused bits of the \fIoptions\fP argument for \fBpcre_dfa_exec()\fP must be zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_\fIxxx\fP, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PARTIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last four of these are exactly the same as for \fBpcre_exec()\fP, so their description is not repeated here. .sp PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT .sp These have the same general effect as they do for \fBpcre_exec()\fP, but the details are slightly different. When PCRE_PARTIAL_HARD is set for \fBpcre_dfa_exec()\fP, it returns PCRE_ERROR_PARTIAL if the end of the subject is reached and there is still at least one matching possibility that requires additional characters. This happens even if some complete matches have also been found. When PCRE_PARTIAL_SOFT is set, 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 possibility. The portion of the string that was inspected when the longest partial match was found is set as the first matching string in both cases. There is a more detailed discussion of partial and multi-segment matching, with examples, in the .\" HREF \fBpcrepartial\fP .\" documentation. .sp PCRE_DFA_SHORTEST .sp 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 alternative algorithm works, this is necessarily the shortest possible match at the first possible matching point in the subject string. .sp PCRE_DFA_RESTART .sp When \fBpcre_dfa_exec()\fP returns a partial match, it is possible to call it again, with additional subject characters, and have it continue with the same match. The PCRE_DFA_RESTART option requests this action; when it is set, the \fIworkspace\fP and \fIwscount\fP 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 .\" HREF \fBpcrepartial\fP .\" documentation. . . .SS "Successful returns from \fBpcre_dfa_exec()\fP" .rs .sp When \fBpcre_dfa_exec()\fP succeeds, it may have matched more than one substring 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, if the pattern .sp <.*> .sp is matched against the string .sp This is no more .sp the three matched strings are .sp .sp 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 \fIovector\fP. Each string uses two elements; the first is the offset to the start, and the second is the offset to the end. In fact, 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 \fBpcre_exec()\fP returns data, even though the meaning of the strings is different.) .P The strings are returned in reverse order of length; that is, the longest matching string is given first. If there were too many matches to fit into \fIovector\fP, the yield of the function is zero, and the vector is filled with the longest matches. Unlike \fBpcre_exec()\fP, \fBpcre_dfa_exec()\fP can use the entire \fIovector\fP for returning matched strings. . . .SS "Error returns from \fBpcre_dfa_exec()\fP" .rs .sp The \fBpcre_dfa_exec()\fP function returns a negative number when it fails. Many of the errors are the same as for \fBpcre_exec()\fP, and these are described .\" HTML .\" above. .\" There are in addition the following errors that are specific to \fBpcre_dfa_exec()\fP: .sp PCRE_ERROR_DFA_UITEM (-16) .sp This return is given if \fBpcre_dfa_exec()\fP encounters an item in the pattern that it does not support, for instance, the use of \eC or a back reference. .sp PCRE_ERROR_DFA_UCOND (-17) .sp This return is given if \fBpcre_dfa_exec()\fP encounters a condition item that uses a back reference for the condition, or a test for recursion in a specific group. These are not supported. .sp PCRE_ERROR_DFA_UMLIMIT (-18) .sp This return is given if \fBpcre_dfa_exec()\fP is called with an \fIextra\fP block that contains a setting of the \fImatch_limit\fP or \fImatch_limit_recursion\fP fields. This is not supported (these fields are meaningless for DFA matching). .sp PCRE_ERROR_DFA_WSSIZE (-19) .sp This return is given if \fBpcre_dfa_exec()\fP runs out of space in the \fIworkspace\fP vector. .sp PCRE_ERROR_DFA_RECURSE (-20) .sp When a recursive subpattern is processed, the matching function calls itself recursively, using private vectors for \fIovector\fP and \fIworkspace\fP. 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. .sp PCRE_ERROR_DFA_BADRESTART (-30) .sp When \fBpcre_dfa_exec()\fP is called with the \fBPCRE_DFA_RESTART\fP option, some plausibility checks are made on the contents of the workspace, which should contain data about the previous partial match. If any of these checks fail, this error is given. . . .SH "SEE ALSO" .rs .sp \fBpcre16\fP(3), \fBpcrebuild\fP(3), \fBpcrecallout\fP(3), \fBpcrecpp(3)\fP(3), \fBpcrematching\fP(3), \fBpcrepartial\fP(3), \fBpcreposix\fP(3), \fBpcreprecompile\fP(3), \fBpcresample\fP(3), \fBpcrestack\fP(3). . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 17 June 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcrecpp.30000644000222100022210000003063311760163326011602 00000000000000.TH PCRECPP 3 "08 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions. .SH "SYNOPSIS OF C++ WRAPPER" .rs .sp .B #include . .SH DESCRIPTION .rs .sp The C++ wrapper for PCRE was provided by Google Inc. Some additional functionality was added by Giuseppe Maxia. This brief man page was constructed from the notes in the \fIpcrecpp.h\fP file, which should be consulted for further details. Note that the C++ wrapper supports only the original 8-bit PCRE library. There is no 16-bit support at present. . . .SH "MATCHING INTERFACE" .rs .sp The "FullMatch" operation checks that supplied text matches a supplied pattern exactly. If pointer arguments are supplied, it copies matched sub-strings that match sub-patterns into them. .sp Example: successful match pcrecpp::RE re("h.*o"); re.FullMatch("hello"); .sp Example: unsuccessful match (requires full match): pcrecpp::RE re("e"); !re.FullMatch("hello"); .sp Example: creating a temporary RE object: pcrecpp::RE("h.*o").FullMatch("hello"); .sp You can pass in a "const char*" or a "string" for "text". The examples below tend to use a const char*. You can, as in the different examples above, store the RE object explicitly in a variable or use a temporary RE object. The examples below use one mode or the other arbitrarily. Either could correctly be used for any of these examples. .P You must supply extra pointer arguments to extract matched subpieces. .sp Example: extracts "ruby" into "s" and 1234 into "i" int i; string s; pcrecpp::RE re("(\e\ew+):(\e\ed+)"); re.FullMatch("ruby:1234", &s, &i); .sp Example: does not try to extract any extra sub-patterns re.FullMatch("ruby:1234", &s); .sp Example: does not try to extract into NULL re.FullMatch("ruby:1234", NULL, &i); .sp Example: integer overflow causes failure !re.FullMatch("ruby:1234567891234", NULL, &i); .sp Example: fails because there aren't enough sub-patterns: !pcrecpp::RE("\e\ew+:\e\ed+").FullMatch("ruby:1234", &s); .sp Example: fails because string cannot be stored in integer !pcrecpp::RE("(.*)").FullMatch("ruby", &i); .sp The provided pointer arguments can be pointers to any scalar numeric type, or one of: .sp string (matched piece is copied to string) StringPiece (StringPiece is mutated to point to matched piece) T (where "bool T::ParseFrom(const char*, int)" exists) NULL (the corresponding matched sub-pattern is not copied) .sp The function returns true iff all of the following conditions are satisfied: .sp a. "text" matches "pattern" exactly; .sp b. The number of matched sub-patterns is >= number of supplied pointers; .sp c. The "i"th argument has a suitable type for holding the string captured as the "i"th sub-pattern. If you pass in void * NULL for the "i"th argument, or a non-void * NULL of the correct type, or pass fewer arguments than the number of sub-patterns, "i"th captured sub-pattern is ignored. .sp CAVEAT: An optional sub-pattern that does not exist in the matched string is assigned the empty string. Therefore, the following will return false (because the empty string is not a valid number): .sp int number; pcrecpp::RE::FullMatch("abc", "[a-z]+(\e\ed+)?", &number); .sp The matching interface supports at most 16 arguments per call. If you need more, consider using the more general interface \fBpcrecpp::RE::DoMatch\fP. See \fBpcrecpp.h\fP for the signature for \fBDoMatch\fP. .P NOTE: Do not use \fBno_arg\fP, which is used internally to mark the end of a list of optional arguments, as a placeholder for missing arguments, as this can lead to segfaults. . . .SH "QUOTING METACHARACTERS" .rs .sp You can use the "QuoteMeta" operation to insert backslashes before all potentially meaningful characters in a string. The returned string, used as a regular expression, will exactly match the original string. .sp Example: string quoted = RE::QuoteMeta(unquoted); .sp Note that it's legal to escape a character even if it has no special meaning in a regular expression -- so this function does that. (This also makes it identical to the perl function of the same name; see "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes "1\e.5\e-2\e.0\e?". . .SH "PARTIAL MATCHES" .rs .sp You can use the "PartialMatch" operation when you want the pattern to match any substring of the text. .sp Example: simple search for a string: pcrecpp::RE("ell").PartialMatch("hello"); .sp Example: find first number in a string: int number; pcrecpp::RE re("(\e\ed+)"); re.PartialMatch("x*100 + 20", &number); assert(number == 100); . . .SH "UTF-8 AND THE MATCHING INTERFACE" .rs .sp By default, pattern and text are plain text, one byte per character. The UTF8 flag, passed to the constructor, causes both pattern and string to be treated as UTF-8 text, still a byte stream but potentially multiple bytes per character. In practice, the text is likelier to be UTF-8 than the pattern, but the match returned may depend on the UTF8 flag, so always use it when matching UTF8 text. For example, "." will match one byte normally but with UTF8 set may match up to three bytes of a multi-byte character. .sp Example: pcrecpp::RE_Options options; options.set_utf8(); pcrecpp::RE re(utf8_pattern, options); re.FullMatch(utf8_string); .sp Example: using the convenience function UTF8(): pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); re.FullMatch(utf8_string); .sp NOTE: The UTF8 flag is ignored if pcre was not configured with the --enable-utf8 flag. . . .SH "PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE" .rs .sp PCRE defines some modifiers to change the behavior of the regular expression engine. The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle to pass such modifiers to a RE class. Currently, the following modifiers are supported: .sp modifier description Perl corresponding .sp PCRE_CASELESS case insensitive match /i PCRE_MULTILINE multiple lines match /m PCRE_DOTALL dot matches newlines /s PCRE_DOLLAR_ENDONLY $ matches only at end N/A PCRE_EXTRA strict escape parsing N/A PCRE_EXTENDED ignore white spaces /x PCRE_UTF8 handles UTF8 chars built-in PCRE_UNGREEDY reverses * and *? N/A PCRE_NO_AUTO_CAPTURE disables capturing parens N/A (*) .sp (*) Both Perl and PCRE allow non capturing parentheses by means of the "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not capture, while (ab|cd) does. .P For a full account on how each modifier works, please check the PCRE API reference page. .P For each modifier, there are two member functions whose name is made out of the modifier in lowercase, without the "PCRE_" prefix. For instance, PCRE_CASELESS is handled by .sp bool caseless() .sp which returns true if the modifier is set, and .sp RE_Options & set_caseless(bool) .sp which sets or unsets the modifier. Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the \fBset_match_limit()\fP and \fBmatch_limit()\fP member functions. Setting \fImatch_limit\fP to a non-zero value will limit the execution of pcre to keep it from doing bad things like blowing the stack or taking an eternity to return a result. A value of 5000 is good enough to stop stack blowup in a 2MB thread stack. Setting \fImatch_limit\fP to zero disables match limiting. Alternatively, you can call \fBmatch_limit_recursion()\fP which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much PCRE recurses. \fBmatch_limit()\fP limits the number of matches PCRE does; \fBmatch_limit_recursion()\fP limits the depth of internal recursion, and therefore the amount of stack that is used. .P Normally, to pass one or more modifiers to a RE class, you declare a \fIRE_Options\fP object, set the appropriate options, and pass this object to a RE constructor. Example: .sp RE_Options opt; opt.set_caseless(true); if (RE("HELLO", opt).PartialMatch("hello world")) ... .sp RE_options has two constructors. The default constructor takes no arguments and creates a set of flags that are off by default. The optional parameter \fIoption_flags\fP is to facilitate transfer of legacy code from C programs. This lets you do .sp RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); .sp However, new code is better off doing .sp RE(pattern, RE_Options().set_caseless(true).set_multiline(true)) .PartialMatch(str); .sp If you are going to pass one of the most used modifiers, there are some convenience functions that return a RE_Options class with the appropriate modifier already set: \fBCASELESS()\fP, \fBUTF8()\fP, \fBMULTILINE()\fP, \fBDOTALL\fP(), and \fBEXTENDED()\fP. .P If you need to set several options at once, and you don't want to go through the pains of declaring a RE_Options object and setting several options, there is a parallel method that give you such ability on the fly. You can concatenate several \fBset_xxxxx()\fP member functions, since each of them returns a reference to its class object. For example, to pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one statement, you may write: .sp RE(" ^ xyz \e\es+ .* blah$", RE_Options() .set_caseless(true) .set_extended(true) .set_multiline(true)).PartialMatch(sometext); .sp . . .SH "SCANNING TEXT INCREMENTALLY" .rs .sp The "Consume" operation may be useful if you want to repeatedly match regular expressions at the front of a string and skip over them as they match. This requires use of the "StringPiece" type, which represents a sub-range of a real string. Like RE, StringPiece is defined in the pcrecpp namespace. .sp Example: read lines of the form "var = value" from a string. string contents = ...; // Fill string somehow pcrecpp::StringPiece input(contents); // Wrap in a StringPiece .sp string var; int value; pcrecpp::RE re("(\e\ew+) = (\e\ed+)\en"); while (re.Consume(&input, &var, &value)) { ...; } .sp Each successful call to "Consume" will set "var/value", and also advance "input" so it points past the matched text. .P The "FindAndConsume" operation is similar to "Consume" but does not anchor your match at the beginning of the string. For example, you could extract all words from a string by repeatedly calling .sp pcrecpp::RE("(\e\ew+)").FindAndConsume(&input, &word) . . .SH "PARSING HEX/OCTAL/C-RADIX NUMBERS" .rs .sp By default, if you pass a pointer to a numeric value, the corresponding text is interpreted as a base-10 number. You can instead wrap the pointer with a call to one of the operators Hex(), Octal(), or CRadix() to interpret the text in another base. The CRadix operator interprets C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to base-10. .sp Example: int a, b, c, d; pcrecpp::RE re("(.*) (.*) (.*) (.*)"); re.FullMatch("100 40 0100 0x40", pcrecpp::Octal(&a), pcrecpp::Hex(&b), pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); .sp will leave 64 in a, b, c, and d. . . .SH "REPLACING PARTS OF STRINGS" .rs .sp You can replace the first match of "pattern" in "str" with "rewrite". Within "rewrite", backslash-escaped digits (\e1 to \e9) can be used to insert text matching corresponding parenthesized group from the pattern. \e0 in "rewrite" refers to the entire matching text. For example: .sp string s = "yabba dabba doo"; pcrecpp::RE("b+").Replace("d", &s); .sp will leave "s" containing "yada dabba doo". The result is true if the pattern matches and a replacement occurs, false otherwise. .P \fBGlobalReplace\fP is like \fBReplace\fP except that it replaces all occurrences of the pattern in the string with the rewrite. Replacements are not subject to re-matching. For example: .sp string s = "yabba dabba doo"; pcrecpp::RE("b+").GlobalReplace("d", &s); .sp will leave "s" containing "yada dada doo". It returns the number of replacements made. .P \fBExtract\fP is like \fBReplace\fP, except that if the pattern matches, "rewrite" is copied into "out" (an additional argument) with substitutions. The non-matching portions of "text" are ignored. Returns true iff a match occurred and the extraction happened successfully; if no match occurs, the string is left unaffected. . . .SH AUTHOR .rs .sp .nf The C++ wrapper was contributed by Google Inc. Copyright (c) 2007 Google Inc. .fi . . .SH REVISION .rs .sp .nf Last updated: 08 January 2012 .fi pcre-8.31/doc/pcrejit.30000644000222100022210000004005311762370425011605 00000000000000.TH PCREJIT 3 "04 May 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE JUST-IN-TIME COMPILER SUPPORT" .rs .sp Just-in-time compiling is a heavyweight optimization that can greatly speed up pattern matching. However, it comes at the cost of extra processing before the match is performed. Therefore, it is of most benefit when the same pattern is going to be matched many times. This does not necessarily mean many calls of a matching function; if the pattern is not anchored, matching attempts may take place many times at various positions in the subject, even for a single call. Therefore, if the subject string is very long, it may still pay to use JIT for one-off matches. .P JIT support applies only to the traditional Perl-compatible matching function. It does not apply when the DFA matching function is being used. The code for this support was written by Zoltan Herczeg. . . .SH "8-BIT and 16-BIT SUPPORT" .rs .sp JIT support is available for both the 8-bit and 16-bit PCRE libraries. To keep this documentation simple, only the 8-bit interface is described in what follows. If you are using the 16-bit library, substitute the 16-bit functions and 16-bit structures (for example, \fIpcre16_jit_stack\fP instead of \fIpcre_jit_stack\fP). . . .SH "AVAILABILITY OF JIT SUPPORT" .rs .sp JIT support is an optional feature of PCRE. The "configure" option --enable-jit (or equivalent CMake option) must be set when PCRE is built if you want to use JIT. The support is limited to the following hardware platforms: .sp ARM v5, v7, and Thumb2 Intel x86 32-bit and 64-bit MIPS 32-bit Power PC 32-bit and 64-bit .sp If --enable-jit is set on an unsupported platform, compilation fails. .P A program that is linked with PCRE 8.20 or later can tell if JIT support is available by calling \fBpcre_config()\fP with the PCRE_CONFIG_JIT option. The result is 1 when JIT is available, and 0 otherwise. However, a simple program does not need to check this in order to use JIT. The API is implemented in a way that falls back to the interpretive code if JIT is not available. .P If your program may sometimes be linked with versions of PCRE that are older than 8.20, but you want to use JIT when it is available, you can test the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT macro such as PCRE_CONFIG_JIT, for compile-time control of your code. . . .SH "SIMPLE USE OF JIT" .rs .sp You have to do two things to make use of the JIT support in the simplest way: .sp (1) Call \fBpcre_study()\fP with the PCRE_STUDY_JIT_COMPILE option for each compiled pattern, and pass the resulting \fBpcre_extra\fP block to \fBpcre_exec()\fP. .sp (2) Use \fBpcre_free_study()\fP to free the \fBpcre_extra\fP block when it is no longer needed, instead of just freeing it yourself. This ensures that any JIT data is also freed. .sp For a program that may be linked with pre-8.20 versions of PCRE, you can insert .sp #ifndef PCRE_STUDY_JIT_COMPILE #define PCRE_STUDY_JIT_COMPILE 0 #endif .sp so that no option is passed to \fBpcre_study()\fP, and then use something like this to free the study data: .sp #ifdef PCRE_CONFIG_JIT pcre_free_study(study_ptr); #else pcre_free(study_ptr); #endif .sp PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for complete matches. If you want to run partial matches using the PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of \fBpcre_exec()\fP, you should set one or both of the following options in addition to, or instead of, PCRE_STUDY_JIT_COMPILE when you call \fBpcre_study()\fP: .sp PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE .sp The JIT compiler generates different optimized code for each of the three modes (normal, soft partial, hard partial). When \fBpcre_exec()\fP is called, the appropriate code is run if it is available. Otherwise, the pattern is matched using interpretive code. .P In some circumstances you may need to call additional functions. These are described in the section entitled .\" HTML .\" "Controlling the JIT stack" .\" below. .P If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ignored, and no JIT data is created. Otherwise, the compiled pattern is passed to the JIT compiler, which turns it into machine code that executes much faster than the normal interpretive code. When \fBpcre_exec()\fP is passed a \fBpcre_extra\fP block containing a pointer to JIT code of the appropriate mode (normal or hard/soft partial), it obeys that code instead of running the interpreter. The result is identical, but the compiled JIT code runs much faster. .P There are some \fBpcre_exec()\fP options that are not supported for JIT execution. There are also some pattern items that JIT cannot handle. Details are given below. In both cases, execution automatically falls back to the interpretive code. If you want to know whether JIT was actually used for a particular match, you should arrange for a JIT callback function to be set up as described in the section entitled .\" HTML .\" "Controlling the JIT stack" .\" below, even if you do not need to supply a non-default JIT stack. Such a callback function is called whenever JIT code is about to be obeyed. If the execution options are not right for JIT execution, the callback function is not obeyed. .P If the JIT compiler finds an unsupported item, no JIT data is generated. You can find out if JIT execution is available after studying a pattern by calling \fBpcre_fullinfo()\fP with the PCRE_INFO_JIT option. A result of 1 means that JIT compilation was successful. A result of 0 means that JIT support is not available, or the pattern was not studied with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to handle the pattern. .P Once a pattern has been studied, with or without JIT, it can be used as many times as you like for matching different subject strings. . . .SH "UNSUPPORTED OPTIONS AND PATTERN ITEMS" .rs .sp The only \fBpcre_exec()\fP options that are supported for JIT execution are PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. .P The unsupported pattern items are: .sp \eC match a single byte; not supported in UTF-8 mode (?Cn) callouts (*PRUNE) ) (*SKIP) ) backtracking control verbs (*THEN) ) .sp Support for some of these may be added in future. . . .SH "RETURN VALUES FROM JIT EXECUTION" .rs .sp When a pattern is matched using JIT execution, the return values are the same as those given by the interpretive \fBpcre_exec()\fP code, with the addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means that the memory used for the JIT stack was insufficient. See .\" HTML .\" "Controlling the JIT stack" .\" below for a discussion of JIT stack usage. For compatibility with the interpretive \fBpcre_exec()\fP code, no more than two-thirds of the \fIovector\fP argument is used for passing back captured substrings. .P The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if searching a very large pattern tree goes on for too long, as it is in the same circumstance when JIT is not used, but the details of exactly what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error code is never returned by JIT execution. . . .SH "SAVING AND RESTORING COMPILED PATTERNS" .rs .sp The code that is generated by the JIT compiler is architecture-specific, and is also position dependent. For those reasons it cannot be saved (in a file or database) and restored later like the bytecode and other data of a compiled pattern. Saving and restoring compiled patterns is not something many people do. More detail about this facility is given in the .\" HREF \fBpcreprecompile\fP .\" documentation. It should be possible to run \fBpcre_study()\fP on a saved and restored pattern, and thereby recreate the JIT data, but because JIT compilation uses significant resources, it is probably not worth doing this; you might as well recompile the original pattern. . . .\" HTML .SH "CONTROLLING THE JIT STACK" .rs .sp When the compiled JIT code runs, it needs a block of memory to use as a stack. By default, it uses 32K on the machine stack. However, some large or complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack. Three functions are provided for managing blocks of memory for use as JIT stacks. There is further discussion about the use of JIT stacks in the section entitled .\" HTML .\" "JIT stack FAQ" .\" below. .P The \fBpcre_jit_stack_alloc()\fP function creates a JIT stack. Its arguments are a starting size and a maximum size, and it returns a pointer to an opaque structure of type \fBpcre_jit_stack\fP, or NULL if there is an error. The \fBpcre_jit_stack_free()\fP function can be used to free a stack that is no longer needed. (For the technically minded: the address space is allocated by mmap or VirtualAlloc.) .P JIT uses far less memory for recursion than the interpretive code, and a maximum stack size of 512K to 1M should be more than enough for any pattern. .P The \fBpcre_assign_jit_stack()\fP function specifies which stack JIT code should use. Its arguments are as follows: .sp pcre_extra *extra pcre_jit_callback callback void *data .sp The \fIextra\fP argument must be the result of studying a pattern with PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other two options: .sp (1) If \fIcallback\fP is NULL and \fIdata\fP is NULL, an internal 32K block on the machine stack is used. .sp (2) If \fIcallback\fP is NULL and \fIdata\fP is not NULL, \fIdata\fP must be a valid JIT stack, the result of calling \fBpcre_jit_stack_alloc()\fP. .sp (3) If \fIcallback\fP is not NULL, it must point to a function that is called with \fIdata\fP as an argument at the start of matching, in order to set up a JIT stack. If the return from the callback function is NULL, the internal 32K stack is used; otherwise the return value must be a valid JIT stack, the result of calling \fBpcre_jit_stack_alloc()\fP. .sp A callback function is obeyed whenever JIT code is about to be run; it is not obeyed when \fBpcre_exec()\fP is called with options that are incompatible for JIT execution. A callback function can therefore be used to determine whether a match operation was executed by JIT or by the interpreter. .P You may safely use the same JIT stack for more than one pattern (either by assigning directly or by callback), as long as the patterns are all matched sequentially in the same thread. In a multithread application, if you do not specify a JIT stack, or if you assign or pass back NULL from a callback, that is thread-safe, because each thread has its own machine stack. However, if you assign or pass back a non-NULL JIT stack, this must be a different stack for each thread so that the application is thread-safe. .P Strictly speaking, even more is allowed. You can assign the same non-NULL stack to any number of patterns as long as they are not used for matching by multiple threads at the same time. For example, you can assign the same stack to all compiled patterns, and use a global mutex in the callback to wait until the stack is available for use. However, this is an inefficient solution, and not recommended. .P This is a suggestion for how a multithreaded program that needs to set up non-default JIT stacks might operate: .sp During thread initalization thread_local_var = pcre_jit_stack_alloc(...) .sp During thread exit pcre_jit_stack_free(thread_local_var) .sp Use a one-line callback function return thread_local_var .sp All the functions described in this section do nothing if JIT is not available, and \fBpcre_assign_jit_stack()\fP does nothing unless the \fBextra\fP argument is non-NULL and points to a \fBpcre_extra\fP block that is the result of a successful study with PCRE_STUDY_JIT_COMPILE etc. . . .\" HTML .SH "JIT STACK FAQ" .rs .sp (1) Why do we need JIT stacks? .sp PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack where the local data of the current node is pushed before checking its child nodes. Allocating real machine stack on some platforms is difficult. For example, the stack chain needs to be updated every time if we extend the stack on PowerPC. Although it is possible, its updating time overhead decreases performance. So we do the recursion in memory. .P (2) Why don't we simply allocate blocks of memory with \fBmalloc()\fP? .sp Modern operating systems have a nice feature: they can reserve an address space instead of allocating memory. We can safely allocate memory pages inside this address space, so the stack could grow without moving memory data (this is important because of pointers). Thus we can allocate 1M address space, and use only a single memory page (usually 4K) if that is enough. However, we can still grow up to 1M anytime if needed. .P (3) Who "owns" a JIT stack? .sp The owner of the stack is the user program, not the JIT studied pattern or anything else. The user program must ensure that if a stack is used by \fBpcre_exec()\fP, (that is, it is assigned to the pattern currently running), that stack must not be used by any other threads (to avoid overwriting the same memory area). The best practice for multithreaded programs is to allocate a stack for each thread, and return this stack through the JIT callback function. .P (4) When should a JIT stack be freed? .sp You can free a JIT stack at any time, as long as it will not be used by \fBpcre_exec()\fP again. When you assign the stack to a pattern, only a pointer is set. There is no reference counting or any other magic. You can free the patterns and stacks in any order, anytime. Just \fIdo not\fP call \fBpcre_exec()\fP with a pattern pointing to an already freed stack, as that will cause SEGFAULT. (Also, do not free a stack currently used by \fBpcre_exec()\fP in another thread). You can also replace the stack for a pattern at any time. You can even free the previous stack before assigning a replacement. .P (5) Should I allocate/free a stack every time before/after calling \fBpcre_exec()\fP? .sp No, because this is too costly in terms of resources. However, you could implement some clever idea which release the stack if it is not used in let's say two minutes. The JIT callback can help to achive this without keeping a list of the currently JIT studied patterns. .P (6) OK, the stack is for long term memory allocation. But what happens if a pattern causes stack overflow with a stack of 1M? Is that 1M kept until the stack is freed? .sp Especially on embedded sytems, it might be a good idea to release memory sometimes without freeing the stack. There is no API for this at the moment. Probably a function call which returns with the currently allocated memory for any stack and another which allows releasing memory (shrinking the stack) would be a good idea if someone needs this. .P (7) This is too much of a headache. Isn't there any better solution for JIT stack handling? .sp No, thanks to Windows. If POSIX threads were used everywhere, we could throw out this complicated API. . . .SH "EXAMPLE CODE" .rs .sp This is a single-threaded example that specifies a JIT stack without using a callback. .sp int rc; int ovector[30]; pcre *re; pcre_extra *extra; pcre_jit_stack *jit_stack; .sp re = pcre_compile(pattern, 0, &error, &erroffset, NULL); /* Check for errors */ extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error); jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); /* Check for error (NULL) */ pcre_assign_jit_stack(extra, NULL, jit_stack); rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30); /* Check results */ pcre_free(re); pcre_free_study(extra); pcre_jit_stack_free(jit_stack); .sp . . .SH "SEE ALSO" .rs .sp \fBpcreapi\fP(3) . . .SH AUTHOR .rs .sp .nf Philip Hazel (FAQ by Zoltan Herczeg) University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 04 May 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_get_substring.30000644000222100022210000000272211735631455014041 00000000000000.TH PCRE_GET_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, .ti +5n .B const char **\fIstringptr\fP); .PP .B int pcre16_get_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, .ti +5n .B PCRE_SPTR16 *\fIstringptr\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for extracting a captured substring. The arguments are: .sp \fIsubject\fP Subject that has been successfully matched \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringnumber\fP Number of the required substring \fIstringptr\fP Where to put the string pointer .sp The memory in which the substring is placed is obtained by calling \fBpcre[16]_malloc()\fP. The convenience function \fBpcre[16]_free_substring()\fP can be used to free it when it is no longer needed. The yield of the function is the length of the substring, PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string number is invalid. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_free_substring.30000644000222100022210000000125211735631322014171 00000000000000.TH PCRE_FREE_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B void pcre_free_substring(const char *\fIstringptr\fP); .PP .B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for freeing the store obtained by a previous call to \fBpcre[16]_get_substring()\fP or \fBpcre[16]_get_named_substring()\fP. Its only argument is a pointer to the string. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcrepattern.30000644000222100022210000035431611770363602012504 00000000000000.TH PCREPATTERN 3 "04 May 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE REGULAR EXPRESSION DETAILS" .rs .sp The syntax and semantics of the regular expressions that are supported by PCRE are described in detail below. There is a quick-reference syntax summary in the .\" HREF \fBpcresyntax\fP .\" page. PCRE tries to match Perl syntax and semantics as closely as it can. PCRE also supports some alternative regular expression syntax (which does not conflict with the Perl syntax) in order to provide some compatibility with regular expressions in Python, .NET, and Oniguruma. .P Perl's regular expressions are described in its own documentation, and regular expressions in general are covered in a number of books, some of which have copious examples. Jeffrey Friedl's "Mastering Regular Expressions", published by O'Reilly, covers regular expressions in great detail. This description of PCRE's regular expressions is intended as reference material. .P The original operation of PCRE was on strings of one-byte characters. However, there is now also support for UTF-8 strings in the original library, and a second library that supports 16-bit and UTF-16 character strings. To use these features, PCRE must be built to include appropriate support. When using UTF strings you must either call the compiling function with the PCRE_UTF8 or PCRE_UTF16 option, or the pattern must start with one of these special sequences: .sp (*UTF8) (*UTF16) .sp Starting a pattern with such a sequence is equivalent to setting the relevant option. This feature is not Perl-compatible. How setting a UTF mode affects pattern matching is mentioned in several places below. There is also a summary of features in the .\" HREF \fBpcreunicode\fP .\" page. .P Another special sequence that may appear at the start of a pattern or in combination with (*UTF8) or (*UTF16) is: .sp (*UCP) .sp This has the same effect as setting the PCRE_UCP option: it causes sequences such as \ed and \ew to use Unicode properties to determine character types, instead of recognizing only characters with codes less than 128 via a lookup table. .P If a pattern starts with (*NO_START_OPT), it has the same effect as setting the PCRE_NO_START_OPTIMIZE option either at compile or matching time. There are also some more of these special sequences that are concerned with the handling of newlines; they are described below. .P The remainder of this document discusses the patterns that are supported by PCRE when one its main matching functions, \fBpcre_exec()\fP (8-bit) or \fBpcre16_exec()\fP (16-bit), is used. PCRE also has alternative matching functions, \fBpcre_dfa_exec()\fP and \fBpcre16_dfa_exec()\fP, which match using a different algorithm that is not Perl-compatible. Some of the features discussed below are not available when DFA matching is used. The advantages and disadvantages of the alternative functions, and how they differ from the normal functions, are discussed in the .\" HREF \fBpcrematching\fP .\" page. . . .\" HTML .SH "NEWLINE CONVENTIONS" .rs .sp PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (linefeed) character, the two-character sequence CRLF, any of the three preceding, or any Unicode newline sequence. The .\" HREF \fBpcreapi\fP .\" page has .\" HTML .\" further discussion .\" about newlines, and shows how to set the newline convention in the \fIoptions\fP arguments for the compiling and matching functions. .P It is also possible to specify a newline convention by starting a pattern string with one of the following five sequences: .sp (*CR) carriage return (*LF) linefeed (*CRLF) carriage return, followed by linefeed (*ANYCRLF) any of the three above (*ANY) all Unicode newline sequences .sp These override the default and the options given to the compiling function. For example, on a Unix system where LF is the default newline sequence, the pattern .sp (*CR)a.b .sp changes the convention to CR. That pattern matches "a\enb" because LF is no longer a newline. Note that these special settings, which are not Perl-compatible, are recognized only at the very start of a pattern, and that they must be in upper case. If more than one of them is present, the last one is used. .P The newline convention affects the interpretation of the dot metacharacter when PCRE_DOTALL is not set, and also the behaviour of \eN. However, it does not affect what the \eR escape sequence matches. By default, this is any Unicode newline sequence, for Perl compatibility. However, this can be changed; see the description of \eR in the section entitled .\" HTML .\" "Newline sequences" .\" below. A change of \eR setting can be combined with a change of newline convention. . . .SH "CHARACTERS AND METACHARACTERS" .rs .sp A regular expression is a pattern that is matched against a subject string from left to right. Most characters stand for themselves in a pattern, and match the corresponding characters in the subject. As a trivial example, the pattern .sp The quick brown fox .sp matches a portion of a subject string that is identical to itself. When caseless matching is specified (the PCRE_CASELESS option), letters are matched independently of case. In a UTF 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 compiled 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 support. .P The power of regular expressions comes from the ability to include alternatives and repetitions in the pattern. These are encoded in the pattern by the use of \fImetacharacters\fP, which do not stand for themselves but instead are interpreted in some special way. .P There are two different sets of metacharacters: those that are recognized anywhere in the pattern except within square brackets, and those that are recognized within square brackets. Outside square brackets, the metacharacters are as follows: .sp \e general escape character with several uses ^ assert start of string (or line, in multiline mode) $ assert end of string (or line, in multiline mode) . match any character except newline (by default) [ start character class definition | start of alternative branch ( start subpattern ) end subpattern ? extends the meaning of ( also 0 or 1 quantifier also quantifier minimizer * 0 or more quantifier + 1 or more quantifier also "possessive quantifier" { start min/max quantifier .sp Part of a pattern that is in square brackets is called a "character class". In a character class the only metacharacters are: .sp \e general escape character ^ negate the class, but only if the first character - indicates character range .\" JOIN [ POSIX character class (only if followed by POSIX syntax) ] terminates the character class .sp The following sections describe the use of each of the metacharacters. . . .SH BACKSLASH .rs .sp The backslash character has several uses. Firstly, if it is followed by a character that is not a number or a letter, it takes away any special meaning that character may have. This use of backslash as an escape character applies both inside and outside character classes. .P For example, if you want to match a * character, you write \e* in the pattern. This escaping action applies whether or not the following character would otherwise be interpreted as a metacharacter, so it is always safe to precede a non-alphanumeric with backslash to specify that it stands for itself. In particular, if you want to match a backslash, you write \e\e. .P In a UTF mode, only ASCII numbers and letters have any special meaning after a backslash. All other characters (in particular, those whose codepoints are greater than 127) are treated as literals. .P If a pattern is compiled with the PCRE_EXTENDED option, white space in the pattern (other than in a character class) and characters between a # outside a character class and the next newline are ignored. An escaping backslash can be used to include a white space or # character as part of the pattern. .P If you want to remove the special meaning from a sequence of characters, you can do so by putting them between \eQ and \eE. This is different from Perl in that $ and @ are handled as literals in \eQ...\eE sequences in PCRE, whereas in Perl, $ and @ cause variable interpolation. Note the following examples: .sp Pattern PCRE matches Perl matches .sp .\" JOIN \eQabc$xyz\eE abc$xyz abc followed by the contents of $xyz \eQabc\e$xyz\eE abc\e$xyz abc\e$xyz \eQabc\eE\e$\eQxyz\eE abc$xyz abc$xyz .sp The \eQ...\eE sequence is recognized both inside and outside character classes. An isolated \eE that is not preceded by \eQ is ignored. If \eQ is not followed by \eE later in the pattern, the literal interpretation continues to the end of the pattern (that is, \eE is assumed at the end). If the isolated \eQ is inside a character class, this causes an error, because the character class is not terminated. . . .\" HTML .SS "Non-printing characters" .rs .sp A second use of backslash provides a way of encoding non-printing characters in patterns in a visible manner. There is no restriction on the appearance of non-printing characters, apart from the binary zero that terminates a pattern, but when a pattern is being prepared by text editing, it is often easier to use one of the following escape sequences than the binary character it represents: .sp \ea alarm, that is, the BEL character (hex 07) \ecx "control-x", where x is any ASCII character \ee escape (hex 1B) \ef form feed (hex 0C) \en linefeed (hex 0A) \er carriage return (hex 0D) \et tab (hex 09) \eddd character with octal code ddd, or back reference \exhh character with hex code hh \ex{hhh..} character with hex code hhh.. (non-JavaScript mode) \euhhhh character with hex code hhhh (JavaScript mode only) .sp The precise effect of \ecx is as follows: if x is a lower case letter, it is converted to upper case. Then bit 6 of the character (hex 40) is inverted. Thus \ecz becomes hex 1A (z is 7A), but \ec{ becomes hex 3B ({ is 7B), while \ec; becomes hex 7B (; is 3B). If the byte following \ec has a value greater than 127, a compile-time error occurs. This locks out non-ASCII characters in all modes. (When PCRE is compiled in EBCDIC mode, all byte values are valid. A lower case letter is converted to upper case, and then the 0xc0 bits are flipped.) .P By default, after \ex, from zero to two hexadecimal digits are read (letters can be in upper or lower case). Any number of hexadecimal digits may appear between \ex{ and }, but the character code is constrained as follows: .sp 8-bit non-UTF mode less than 0x100 8-bit UTF-8 mode less than 0x10ffff and a valid codepoint 16-bit non-UTF mode less than 0x10000 16-bit UTF-16 mode less than 0x10ffff and a valid codepoint .sp Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called "surrogate" codepoints). .P If characters other than hexadecimal digits appear between \ex{ and }, or if there is no terminating }, this form of escape is not recognized. Instead, the initial \ex will be interpreted as a basic hexadecimal escape, with no following digits, giving a character whose value is zero. .P If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \ex is as just described only when it is followed by two hexadecimal digits. Otherwise, it matches a literal "x" character. In JavaScript mode, support for code points greater than 256 is provided by \eu, which must be followed by four hexadecimal digits; otherwise it matches a literal "u" character. Character codes specified by \eu in JavaScript mode are constrained in the same was as those specified by \ex in non-JavaScript mode. .P Characters whose value is less than 256 can be defined by either of the two syntaxes for \ex (or by \eu in JavaScript mode). There is no difference in the way they are handled. For example, \exdc is exactly the same as \ex{dc} (or \eu00dc in JavaScript mode). .P After \e0 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 \e0\ex\e07 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. .P The handling of a backslash followed by a digit other than 0 is complicated. Outside a character class, PCRE reads it and any following digits 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 \fIback reference\fP. A description of how this works is given .\" HTML .\" later, .\" following the discussion of .\" HTML .\" parenthesized subpatterns. .\" .P 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 uses them to generate a data character. Any subsequent digits stand for themselves. The value of the character is constrained in the same way as characters specified in hexadecimal. For example: .sp \e040 is another way of writing a space .\" JOIN \e40 is the same, provided there are fewer than 40 previous capturing subpatterns \e7 is always a back reference .\" JOIN \e11 might be a back reference, or another way of writing a tab \e011 is always a tab \e0113 is a tab followed by the character "3" .\" JOIN \e113 might be a back reference, otherwise the character with octal code 113 .\" JOIN \e377 might be a back reference, otherwise the value 255 (decimal) .\" JOIN \e81 is either a back reference, or a binary zero followed by the two characters "8" and "1" .sp 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. .P All the sequences that define a single character value can be used both inside and outside character classes. In addition, inside a character class, \eb is interpreted as the backspace character (hex 08). .P \eN is not allowed in a character class. \eB, \eR, and \eX are not special inside a character class. Like other unrecognized escape sequences, they are treated as the literal characters "B", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is set. Outside a character class, these sequences have different meanings. . . .SS "Unsupported escape sequences" .rs .sp In Perl, the sequences \el, \eL, \eu, and \eU are recognized by its string handler and used to modify the case of following characters. By default, PCRE does not support these escape sequences. However, if the PCRE_JAVASCRIPT_COMPAT option is set, \eU matches a "U" character, and \eu can be used to define a character by code point, as described in the previous section. . . .SS "Absolute and relative back references" .rs .sp The sequence \eg followed by an unsigned or a negative number, optionally enclosed in braces, is an absolute or relative back reference. A named back reference can be coded as \eg{name}. Back references are discussed .\" HTML .\" later, .\" following the discussion of .\" HTML .\" parenthesized subpatterns. .\" . . .SS "Absolute and relative subroutine calls" .rs .sp For compatibility with Oniguruma, the non-Perl syntax \eg followed by a name or a number enclosed either in angle brackets or single quotes, is an alternative syntax for referencing a subpattern as a "subroutine". Details are discussed .\" HTML .\" later. .\" Note that \eg{...} (Perl syntax) and \eg<...> (Oniguruma syntax) are \fInot\fP synonymous. The former is a back reference; the latter is a .\" HTML .\" subroutine .\" call. . . .\" HTML .SS "Generic character types" .rs .sp Another use of backslash is for specifying generic character types: .sp \ed any decimal digit \eD any character that is not a decimal digit \eh any horizontal white space character \eH any character that is not a horizontal white space character \es any white space character \eS any character that is not a white space character \ev any vertical white space character \eV any character that is not a vertical white space character \ew any "word" character \eW any "non-word" character .sp There is also the single sequence \eN, which matches a non-newline character. This is the same as .\" HTML .\" the "." metacharacter .\" when PCRE_DOTALL is not set. Perl also uses \eN to match characters by name; PCRE does not support this. .P Each pair of lower and upper case escape sequences partitions the complete set of characters into two disjoint sets. Any given character matches one, and only one, of each pair. The sequences can appear both inside and outside character classes. They each match one character of the appropriate type. If the current matching point is at the end of the subject string, all of them fail, because there is no character to match. .P For compatibility with Perl, \es does not match the VT character (code 11). This makes it different from the the POSIX "space" class. The \es characters are HT (9), LF (10), FF (12), CR (13), and space (32). If "use locale;" is included in a Perl script, \es may match the VT character. In PCRE, it never does. .P A "word" character is an underscore or any character that is a letter or digit. By default, the definition of letters and digits is controlled by PCRE's low-valued character tables, and may vary if locale-specific matching is taking place (see .\" HTML .\" "Locale support" .\" in the .\" HREF \fBpcreapi\fP .\" page). For example, in a French locale such as "fr_FR" in Unix-like systems, or "french" in Windows, some character codes greater than 128 are used for accented letters, and these are then matched by \ew. The use of locales with Unicode is discouraged. .P By default, in a UTF mode, characters with values greater than 128 never match \ed, \es, or \ew, and always match \eD, \eS, and \eW. These sequences retain their original meanings from before UTF support was available, mainly for efficiency reasons. However, if PCRE is compiled with Unicode property support, and the PCRE_UCP option is set, the behaviour is changed so that Unicode properties are used to determine character types, as follows: .sp \ed any character that \ep{Nd} matches (decimal digit) \es any character that \ep{Z} matches, plus HT, LF, FF, CR \ew any character that \ep{L} or \ep{N} matches, plus underscore .sp The upper case escapes match the inverse sets of characters. Note that \ed matches only decimal digits, whereas \ew matches any Unicode digit, as well as any Unicode letter, and underscore. Note also that PCRE_UCP affects \eb, and \eB because they are defined in terms of \ew and \eW. Matching these sequences is noticeably slower when PCRE_UCP is set. .P The sequences \eh, \eH, \ev, and \eV are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII characters by default, these always match certain high-valued codepoints, whether or not PCRE_UCP is set. The horizontal space characters are: .sp U+0009 Horizontal tab U+0020 Space U+00A0 Non-break space U+1680 Ogham space mark U+180E Mongolian vowel separator U+2000 En quad U+2001 Em quad U+2002 En space U+2003 Em space U+2004 Three-per-em space U+2005 Four-per-em space U+2006 Six-per-em space U+2007 Figure space U+2008 Punctuation space U+2009 Thin space U+200A Hair space U+202F Narrow no-break space U+205F Medium mathematical space U+3000 Ideographic space .sp The vertical space characters are: .sp U+000A Linefeed U+000B Vertical tab U+000C Form feed U+000D Carriage return U+0085 Next line U+2028 Line separator U+2029 Paragraph separator .sp In 8-bit, non-UTF-8 mode, only the characters with codepoints less than 256 are relevant. . . .\" HTML .SS "Newline sequences" .rs .sp Outside a character class, by default, the escape sequence \eR matches any Unicode newline sequence. In 8-bit non-UTF-8 mode \eR is equivalent to the following: .sp (?>\er\en|\en|\ex0b|\ef|\er|\ex85) .sp This is an example of an "atomic group", details of which are given .\" HTML .\" below. .\" This particular group matches either the two-character sequence CR followed by LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab, U+000B), FF (form feed, U+000C), CR (carriage return, U+000D), or NEL (next line, U+0085). The two-character sequence is treated as a single unit that cannot be split. .P In other modes, two additional characters whose codepoints are greater than 255 are added: LS (line separator, U+2028) and PS (paragraph separator, U+2029). Unicode character property support is not needed for these characters to be recognized. .P It is possible to restrict \eR to match only CR, LF, or CRLF (instead of the complete set of Unicode line endings) by setting the option PCRE_BSR_ANYCRLF either at compile time or when the pattern is matched. (BSR is an abbrevation for "backslash R".) This can be made the default when PCRE is built; if this is the case, the other behaviour can be requested via the PCRE_BSR_UNICODE option. It is also possible to specify these settings by starting a pattern string with one of the following sequences: .sp (*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence .sp These override the default and the options given to the compiling function, but they can themselves be overridden by options given to a matching function. Note that these special settings, which are not Perl-compatible, are recognized only at the very start of a pattern, and that they must be in upper case. If more than one of them is present, the last one is used. They can be combined with a change of newline convention; for example, a pattern can start with: .sp (*ANY)(*BSR_ANYCRLF) .sp They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special sequences. Inside a character class, \eR is treated as an unrecognized escape sequence, and so matches the letter "R" by default, but causes an error if PCRE_EXTRA is set. . . .\" HTML .SS Unicode character properties .rs .sp When PCRE is built with Unicode character property support, three additional escape sequences that match characters with specific properties are available. When in 8-bit non-UTF-8 mode, these sequences are of course limited to testing characters whose codepoints are less than 256, but they do work in this mode. The extra escape sequences are: .sp \ep{\fIxx\fP} a character with the \fIxx\fP property \eP{\fIxx\fP} a character without the \fIxx\fP property \eX an extended Unicode sequence .sp The property names represented by \fIxx\fP above are limited to the Unicode script names, the general category properties, "Any", which matches any character (including newline), and some special PCRE properties (described in the .\" HTML .\" next section). .\" Other Perl properties such as "InMusicalSymbols" are not currently supported by PCRE. Note that \eP{Any} does not match any characters, so always causes a match failure. .P Sets of Unicode characters are defined as belonging to certain scripts. A character from one of these sets can be matched using a script name. For example: .sp \ep{Greek} \eP{Han} .sp Those that are not part of an identified script are lumped together as "Common". The current list of scripts is: .P Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi. .P Each character has exactly one Unicode general category property, specified by a two-letter abbreviation. For compatibility with Perl, negation can be specified by including a circumflex between the opening brace and the property name. For example, \ep{^Lu} is the same as \eP{Lu}. .P If only one letter is specified with \ep or \eP, it includes all the general category properties that start with that letter. In this case, in the absence of negation, the curly brackets in the escape sequence are optional; these two examples have the same effect: .sp \ep{L} \epL .sp The following general category property codes are supported: .sp C Other Cc Control Cf Format Cn Unassigned Co Private use Cs Surrogate .sp L Letter Ll Lower case letter Lm Modifier letter Lo Other letter Lt Title case letter Lu Upper case letter .sp M Mark Mc Spacing mark Me Enclosing mark Mn Non-spacing mark .sp N Number Nd Decimal number Nl Letter number No Other number .sp P Punctuation Pc Connector punctuation Pd Dash punctuation Pe Close punctuation Pf Final punctuation Pi Initial punctuation Po Other punctuation Ps Open punctuation .sp S Symbol Sc Currency symbol Sk Modifier symbol Sm Mathematical symbol So Other symbol .sp Z Separator Zl Line separator Zp Paragraph separator Zs Space separator .sp The special property L& is also supported: it matches a character that has the Lu, Ll, or Lt property, in other words, a letter that is not classified as a modifier or "other". .P The Cs (Surrogate) property applies only to characters in the range U+D800 to U+DFFF. Such characters are not valid in Unicode strings and so cannot be tested by PCRE, unless UTF validity checking has been turned off (see the discussion of PCRE_NO_UTF8_CHECK and PCRE_NO_UTF16_CHECK in the .\" HREF \fBpcreapi\fP .\" page). Perl does not support the Cs property. .P The long synonyms for property names that Perl supports (such as \ep{Letter}) are not supported by PCRE, nor is it permitted to prefix any of these properties with "Is". .P No character that is in the Unicode table has the Cn (unassigned) property. Instead, this property is assumed for any code point that is not in the Unicode table. .P Specifying caseless matching does not affect these escape sequences. For example, \ep{Lu} always matches only upper case letters. .P The \eX escape matches any number of Unicode characters that form an extended Unicode sequence. \eX is equivalent to .sp (?>\ePM\epM*) .sp That is, it matches a character without the "mark" property, followed by zero or more characters with the "mark" property, and treats the sequence as an atomic group .\" HTML .\" (see below). .\" Characters with the "mark" property are typically accents that affect the preceding character. None of them have codepoints less than 256, so in 8-bit non-UTF-8 mode \eX matches any one character. .P Note that recent versions of Perl have changed \eX to match what Unicode calls an "extended grapheme cluster", which has a more complicated definition. .P Matching characters by Unicode property is not fast, because PCRE has to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \ed and \ew do not use Unicode properties in PCRE by default, though you can make them do so by setting the PCRE_UCP option or by starting the pattern with (*UCP). . . .\" HTML .SS PCRE's additional properties .rs .sp As well as the standard Unicode properties described in the previous section, PCRE supports four more that make it possible to convert traditional escape sequences such as \ew and \es and POSIX character classes to use Unicode properties. PCRE uses these non-standard, non-Perl properties internally when PCRE_UCP is set. They are: .sp Xan Any alphanumeric character Xps Any POSIX space character Xsp Any Perl space character Xwd Any Perl "word" character .sp Xan matches characters that have either the L (letter) or the N (number) property. Xps matches the characters tab, linefeed, vertical tab, form feed, or carriage return, and any other character that has the Z (separator) property. Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the same characters as Xan, plus underscore. . . .\" HTML .SS "Resetting the match start" .rs .sp The escape sequence \eK causes any previously matched characters not to be included in the final matched sequence. For example, the pattern: .sp foo\eKbar .sp matches "foobar", but reports that it has matched "bar". This feature is similar to a lookbehind assertion .\" HTML .\" (described below). .\" However, in this case, the part of the subject before the real match does not have to be of fixed length, as lookbehind assertions do. The use of \eK does not interfere with the setting of .\" HTML .\" captured substrings. .\" For example, when the pattern .sp (foo)\eKbar .sp matches "foobar", the first substring is still set to "foo". .P Perl documents that the use of \eK within assertions is "not well defined". In PCRE, \eK is acted upon when it occurs inside positive assertions, but is ignored in negative assertions. . . .\" HTML .SS "Simple assertions" .rs .sp The final use of backslash is for certain simple assertions. An assertion specifies a condition that has to be met at a particular point in a match, without consuming any characters from the subject string. The use of subpatterns for more complicated assertions is described .\" HTML .\" below. .\" The backslashed assertions are: .sp \eb matches at a word boundary \eB matches when not at a word boundary \eA matches at the start of the subject \eZ matches at the end of the subject also matches before a newline at the end of the subject \ez matches only at the end of the subject \eG matches at the first matching position in the subject .sp Inside a character class, \eb has a different meaning; it matches the backspace character. If any other of these assertions appears in a character class, by default it matches the corresponding literal character (for example, \eB matches the letter B). However, if the PCRE_EXTRA option is set, an "invalid escape sequence" error is generated instead. .P A word boundary is a position in the subject string where the current character and the previous character do not both match \ew or \eW (i.e. one matches \ew and the other matches \eW), or the start or end of the string if the first or last character matches \ew, respectively. In a UTF mode, the meanings of \ew and \eW can be changed by setting the PCRE_UCP option. When this is done, it also affects \eb and \eB. Neither PCRE nor Perl has a separate "start of word" or "end of word" metasequence. However, whatever follows \eb normally determines which it is. For example, the fragment \eba matches "a" at the start of a word. .P The \eA, \eZ, and \ez assertions differ from the traditional circumflex and dollar (described in the next section) in that they only ever match at the very start and end of the subject string, whatever options are set. Thus, they are independent of multiline mode. These three assertions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which affect only the behaviour of the circumflex and dollar metacharacters. However, if the \fIstartoffset\fP argument of \fBpcre_exec()\fP is non-zero, indicating that matching is to start at a point other than the beginning of the subject, \eA can never match. The difference between \eZ and \ez is that \eZ matches before a newline at the end of the string as well as at the very end, whereas \ez matches only at the end. .P The \eG assertion is true only when the current matching position is at the start point of the match, as specified by the \fIstartoffset\fP argument of \fBpcre_exec()\fP. It differs from \eA when the value of \fIstartoffset\fP is non-zero. By calling \fBpcre_exec()\fP multiple times with appropriate arguments, you can mimic Perl's /g option, and it is in this kind of implementation where \eG can be useful. .P Note, however, that PCRE's interpretation of \eG, 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 at a time, it cannot reproduce this behaviour. .P If all the alternatives of a pattern begin with \eG, the expression is anchored to the starting match position, and the "anchored" flag is set in the compiled regular expression. . . .SH "CIRCUMFLEX AND DOLLAR" .rs .sp 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 \fIstartoffset\fP argument of \fBpcre_exec()\fP is non-zero, circumflex can never match if the PCRE_MULTILINE option is unset. Inside a character class, circumflex has an entirely different meaning .\" HTML .\" (see below). .\" .P 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 subject, it is said to be an "anchored" pattern. (There are also other constructs that can cause a pattern to be anchored.) .P 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. .P 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 \eZ assertion. .P The meanings of the circumflex and dollar characters are changed if the 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. .P For example, the pattern /^abc$/ matches the subject string "def\enabc" (where \en 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 \fIstartoffset\fP argument of \fBpcre_exec()\fP is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is set. .P Note that the sequences \eA, \eZ, and \ez can be used to match the start and end of the subject in both modes, and if all branches of a pattern start with \eA it is always anchored, whether or not PCRE_MULTILINE is set. . . .\" HTML .SH "FULL STOP (PERIOD, DOT) AND \eN" .rs .sp Outside a character class, a dot in the pattern matches any one character in the subject string except (by default) a character that signifies the end of a line. .P When a line ending is defined as a single character, dot never matches that character; when the two-character sequence CRLF is used, dot does not match CR if it is immediately followed by LF, but otherwise it matches all characters (including isolated CRs and LFs). When any Unicode line endings are being recognized, dot does not match CR or LF or any of the other line ending characters. .P 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 the two-character sequence CRLF is present in the subject string, it takes two dots to match it. .P The handling of dot is entirely independent of the handling of circumflex and dollar, the only relationship being that they both involve newlines. Dot has no special meaning in a character class. .P The escape sequence \eN behaves like a dot, except that it is not affected by the PCRE_DOTALL option. In other words, it matches any character except one that signifies the end of a line. Perl also uses \eN to match characters by name; PCRE does not support this. . . .SH "MATCHING A SINGLE DATA UNIT" .rs .sp Outside a character class, the escape sequence \eC matches any one data unit, whether or not a UTF mode is set. In the 8-bit library, one data unit is one byte; in the 16-bit library it is a 16-bit unit. Unlike a dot, \eC always matches line-ending characters. The feature is provided in Perl in order to match individual bytes in UTF-8 mode, but it is unclear how it can usefully be used. Because \eC breaks up characters into individual data units, matching one unit with \eC in a UTF mode means that the rest of the string may start with a malformed UTF character. This has undefined results, because PCRE assumes that it is dealing with valid UTF strings (and by default it checks this at the start of processing unless the PCRE_NO_UTF8_CHECK or PCRE_NO_UTF16_CHECK option is used). .P PCRE does not allow \eC to appear in lookbehind assertions .\" HTML .\" (described below) .\" in a UTF mode, because this would make it impossible to calculate the length of the lookbehind. .P In general, the \eC escape sequence is best avoided. However, one way of using it that avoids the problem of malformed UTF characters is to use a lookahead to check the length of the next character, as in this pattern, which could be used with a UTF-8 string (ignore white space and line breaks): .sp (?| (?=[\ex00-\ex7f])(\eC) | (?=[\ex80-\ex{7ff}])(\eC)(\eC) | (?=[\ex{800}-\ex{ffff}])(\eC)(\eC)(\eC) | (?=[\ex{10000}-\ex{1fffff}])(\eC)(\eC)(\eC)(\eC)) .sp A group that starts with (?| resets the capturing parentheses numbers in each alternative (see .\" HTML .\" "Duplicate Subpattern Numbers" .\" below). The assertions at the start of each branch check the next UTF-8 character for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The character's individual bytes are then captured by the appropriate number of groups. . . .\" HTML .SH "SQUARE BRACKETS AND CHARACTER CLASSES" .rs .sp An opening square bracket introduces a character class, terminated by a closing square bracket. A closing square bracket on its own is not special by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, a lone closing square bracket causes a compile-time error. If a closing square bracket is required as a member of the class, it should be the first data character in the class (after an initial circumflex, if present) or escaped with a backslash. .P A character class matches a single character in the subject. In a UTF mode, the character may be more than one data unit long. A matched character must be in the set of characters defined by the class, unless the first character in the class definition is a circumflex, in which case the subject character must not be in the set defined by the class. If a circumflex is actually required as a member of the class, ensure it is not the first character, or escape it with a backslash. .P For example, the character class [aeiou] matches any lower case vowel, while [^aeiou] matches any character that is not a lower case vowel. Note that a circumflex is just a convenient notation for specifying the characters that are in the class by enumerating those that are not. A class that starts with a circumflex is not an assertion; it still consumes a character from the subject string, and therefore it fails if the current pointer is at the end of the string. .P In UTF-8 (UTF-16) mode, characters with values greater than 255 (0xffff) can be included in a class as a literal string of data units, or by using the \ex{ escaping mechanism. .P When caseless matching is set, any letters in a class represent both their upper case and lower case versions, so for example, a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a caseful version would. In a UTF 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 compiled with Unicode property support, but not otherwise. If you want to use caseless matching in a UTF mode for characters 128 and above, you must ensure that PCRE is compiled with Unicode property support as well as with UTF support. .P Characters that might indicate line breaks 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. .P The minus (hyphen) character can be used to specify a range of characters in a character class. For example, [d-m] matches any letter between d and m, inclusive. If a minus character is required in a class, it must be escaped with a backslash or appear in a position where it cannot be interpreted as indicating a range, typically as the first or last character in the class. .P It is not possible to have the literal character "]" as the end character of a range. A pattern such as [W-]46] is interpreted as a class of two characters ("W" and "-") followed by a literal string "46]", so it would match "W46]" or "-46]". However, if the "]" is escaped with a backslash it is interpreted as the end of range, so [W-\e]46] is interpreted as a class containing a range followed by two other characters. The octal or hexadecimal representation of "]" can also be used to end a range. .P Ranges operate in the collating sequence of character values. They can also be used for characters specified numerically, for example [\e000-\e037]. Ranges can include any characters that are valid for the current mode. .P If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent to [][\e\e^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character tables for a French locale are in use, [\exc8-\excb] matches accented E characters in both cases. In UTF modes, PCRE supports the concept of case for characters with values greater than 128 only when it is compiled with Unicode property support. .P The character escape sequences \ed, \eD, \eh, \eH, \ep, \eP, \es, \eS, \ev, \eV, \ew, and \eW may appear in a character class, and add the characters that they match to the class. For example, [\edABCDEF] matches any hexadecimal digit. In UTF modes, the PCRE_UCP option affects the meanings of \ed, \es, \ew and their upper case partners, just as it does when they appear outside a character class, as described in the section entitled .\" HTML .\" "Generic character types" .\" above. The escape sequence \eb has a different meaning inside a character class; it matches the backspace character. The sequences \eB, \eN, \eR, and \eX are not special inside a character class. Like any other unrecognized escape sequences, they are treated as the literal characters "B", "N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is set. .P A circumflex can conveniently be used with the upper case character types to specify a more restricted set of characters than the matching lower case type. For example, the class [^\eW_] matches any letter or digit, but not underscore, whereas [\ew] includes underscore. A positive character class should be read as "something OR something OR ..." and a negative class as "NOT something AND NOT something AND NOT ...". .P The only metacharacters that are recognized in character classes are backslash, hyphen (only where it can be interpreted as specifying a range), circumflex (only at the start), opening square bracket (only when it can be interpreted as introducing a POSIX class name - see the next section), and the terminating closing square bracket. However, escaping other non-alphanumeric characters does no harm. . . .SH "POSIX CHARACTER CLASSES" .rs .sp Perl supports the POSIX notation for character classes. This uses names enclosed by [: and :] within the enclosing square brackets. PCRE also supports this notation. For example, .sp [01[:alpha:]%] .sp matches "0", "1", any alphabetic character, or "%". The supported class names are: .sp alnum letters and digits alpha letters ascii character codes 0 - 127 blank space or tab only cntrl control characters digit decimal digits (same as \ed) graph printing characters, excluding space lower lower case letters print printing characters, including space punct printing characters, excluding letters and digits and space space white space (not quite the same as \es) upper upper case letters word "word" characters (same as \ew) xdigit hexadecimal digits .sp The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), and space (32). Notice that this list includes the VT character (code 11). This makes "space" different to \es, which does not include VT (for Perl compatibility). .P The name "word" is a Perl extension, and "blank" is a GNU extension from Perl 5.8. Another Perl extension is negation, which is indicated by a ^ character after the colon. For example, .sp [12[:^digit:]] .sp matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered. .P By default, in UTF modes, characters with values greater than 128 do not match any of the POSIX character classes. However, if the PCRE_UCP option is passed to \fBpcre_compile()\fP, some of the classes are changed so that Unicode character properties are used. This is achieved by replacing the POSIX classes by other sequences, as follows: .sp [:alnum:] becomes \ep{Xan} [:alpha:] becomes \ep{L} [:blank:] becomes \eh [:digit:] becomes \ep{Nd} [:lower:] becomes \ep{Ll} [:space:] becomes \ep{Xps} [:upper:] becomes \ep{Lu} [:word:] becomes \ep{Xwd} .sp Negated versions, such as [:^alpha:] use \eP instead of \ep. The other POSIX classes are unchanged, and match only characters with code points less than 128. . . .SH "VERTICAL BAR" .rs .sp Vertical bar characters are used to separate alternative patterns. For example, the pattern .sp gilbert|sullivan .sp 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 alternatives are within a subpattern .\" HTML .\" (defined below), .\" "succeeds" means matching the rest of the main pattern as well as the alternative in the subpattern. . . .SH "INTERNAL OPTION SETTING" .rs .sp The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and PCRE_EXTENDED options (which are Perl-compatible) can be changed from within the pattern by a sequence of Perl option letters enclosed between "(?" and ")". The option letters are .sp i for PCRE_CASELESS m for PCRE_MULTILINE s for PCRE_DOTALL x for PCRE_EXTENDED .sp For example, (?im) sets caseless, multiline matching. It is also possible to unset these options by preceding the letter with a hyphen, and a combined setting and unsetting such as (?im-sx), which sets PCRE_CASELESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, is also permitted. If a letter appears both before and after the hyphen, the option is unset. .P 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. .P When one of these option changes occurs at top level (that is, not inside subpattern parentheses), the change applies to the remainder of the pattern that follows. If the change is placed right at the start of a pattern, PCRE extracts it into the global options (and it will therefore show up in data extracted by the \fBpcre_fullinfo()\fP function). .P An option change within a subpattern (see below for a description of subpatterns) affects only that part of the subpattern that follows it, so .sp (a(?i)b)c .sp matches abc and aBc and no other strings (assuming PCRE_CASELESS is not used). By this means, options can be made to have different settings in different parts of the pattern. Any changes made in one alternative do carry on into subsequent branches within the same subpattern. For example, .sp (a(?i)b|c) .sp matches "ab", "aB", "c", and "C", even though when matching "C" the first branch is abandoned before the option setting. This is because the effects of option settings happen at compile time. There would be some very weird behaviour otherwise. .P \fBNote:\fP There are other PCRE-specific options that can be set by the application when the compiling or matching functions are called. In some cases the pattern can contain special leading sequences such as (*CRLF) to override what the application has set or what has been defaulted. Details are given in the section entitled .\" HTML .\" "Newline sequences" .\" above. There are also the (*UTF8), (*UTF16), and (*UCP) leading sequences that can be used to set UTF and Unicode property modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, and the PCRE_UCP options, respectively. . . .\" HTML .SH SUBPATTERNS .rs .sp Subpatterns are delimited by parentheses (round brackets), which can be nested. Turning part of a pattern into a subpattern does two things: .sp 1. It localizes a set of alternatives. For example, the pattern .sp cat(aract|erpillar|) .sp matches "cataract", "caterpillar", or "cat". Without the parentheses, it would match "cataract", "erpillar" or an empty string. .sp 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 \fIovector\fP argument of the matching function. (This applies only to the traditional matching functions; the DFA matching functions do not support capturing.) .P 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 pattern .sp the ((red|white) (king|queen)) .sp the captured substrings are "red king", "red", and "king", and are numbered 1, 2, and 3, respectively. .P 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 capturing, 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 .sp the ((?:red|white) (king|queen)) .sp the captured substrings are "white queen" and "queen", and are numbered 1 and 2. The maximum number of capturing subpatterns is 65535. .P 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 .sp (?i:saturday|sunday) (?:(?i)saturday|sunday) .sp 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 "Saturday". . . .\" HTML .SH "DUPLICATE SUBPATTERN NUMBERS" .rs .sp Perl 5.10 introduced a feature whereby each alternative in a subpattern uses the same numbers for its capturing parentheses. Such a subpattern starts with (?| and is itself a non-capturing subpattern. For example, consider this pattern: .sp (?|(Sat)ur|(Sun))day .sp Because the two alternatives are inside a (?| group, both sets of capturing parentheses are numbered one. Thus, when the pattern matches, you can look at captured substring number one, whichever alternative matched. This construct is useful when you want to capture part, but not all, of one of a number of alternatives. Inside a (?| group, parentheses are numbered as usual, but the number is reset at the start of each branch. The numbers of any capturing parentheses that follow the subpattern start after the highest number used in any branch. The following example is taken from the Perl documentation. The numbers underneath show in which buffer the captured content will be stored. .sp # before ---------------branch-reset----------- after / ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x # 1 2 2 3 2 3 4 .sp A back reference to a numbered subpattern uses the most recent value that is set for that number by any subpattern. The following pattern matches "abcabc" or "defdef": .sp /(?|(abc)|(def))\e1/ .sp In contrast, a subroutine call to a numbered subpattern always refers to the first one in the pattern with the given number. The following pattern matches "abcabc" or "defabc": .sp /(?|(abc)|(def))(?1)/ .sp If a .\" HTML .\" condition test .\" for a subpattern's having matched refers to a non-unique number, the test is true if any of the subpatterns of that number have matched. .P An alternative approach to using this "branch reset" feature is to use duplicate named subpatterns, as described in the next section. . . .SH "NAMED SUBPATTERNS" .rs .sp Identifying capturing parentheses by number is simple, but it can be very hard to keep track of the numbers in complicated regular expressions. Furthermore, if an expression is modified, the numbers may change. To help with this difficulty, PCRE supports the naming of subpatterns. This feature was not added to Perl until release 5.10. Python had the feature earlier, and PCRE introduced it at release 4.0, using the Python syntax. PCRE now supports both the Perl and the Python syntax. Perl allows identically numbered subpatterns to have different names, but PCRE does not. .P In PCRE, a subpattern can be named in one of three ways: (?...) or (?'name'...) as in Perl, or (?P...) as in Python. References to capturing parentheses from other parts of the pattern, such as .\" HTML .\" back references, .\" .\" HTML .\" recursion, .\" and .\" HTML .\" conditions, .\" can be made by name as well as by number. .P Names consist of up to 32 alphanumeric characters and underscores. Named capturing parentheses are still allocated numbers as well as names, exactly as if the names were not present. The PCRE API provides function calls for extracting the name-to-number translation table from a compiled pattern. There is also a convenience function for extracting a captured substring by name. .P 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. (Duplicate names are also always permitted for subpatterns with the same number, set up as described in the previous section.) Duplicate names 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: .sp (?Mon|Fri|Sun)(?:day)?| (?Tue)(?:sday)?| (?Wed)(?:nesday)?| (?Thu)(?:rsday)?| (?Sat)(?:urday)? .sp There are five capturing substrings, but only one is ever set after a match. (An alternative way of solving this problem is to use a "branch reset" subpattern, as described in the previous section.) .P 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. .P If you make a back reference to a non-unique named subpattern from elsewhere in the pattern, the one that corresponds to the first occurrence of the name is used. In the absence of duplicate numbers (see the previous section) this is the one with the lowest number. If you use a named reference in a condition test (see the .\" .\" HTML .\" section about conditions .\" below), either to check whether a subpattern has matched, or to check for recursion, all subpatterns with the same name are tested. If the condition is true for any one of them, the overall condition is true. This is the same behaviour as testing by number. For further details of the interfaces for handling named subpatterns, see the .\" HREF \fBpcreapi\fP .\" documentation. .P \fBWarning:\fP You cannot use different names to distinguish between two subpatterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if different names are given to subpatterns with the same number. However, you can give the same name to subpatterns with the same number, even when PCRE_DUPNAMES is not set. . . .SH REPETITION .rs .sp Repetition is specified by quantifiers, which can follow any of the following items: .sp a literal data character the dot metacharacter the \eC escape sequence the \eX escape sequence the \eR escape sequence an escape such as \ed or \epL that matches a single character a character class a back reference (see next section) a parenthesized subpattern (including assertions) a subroutine call to a subpattern (recursive or otherwise) .sp The general repetition quantifier specifies a minimum and maximum number of permitted matches, by giving the two numbers in curly brackets (braces), separated by a comma. The numbers must be less than 65536, and the first must be less than or equal to the second. For example: .sp z{2,4} .sp matches "zz", "zzz", or "zzzz". A closing brace on its own is not a special character. If the second number is omitted, but the comma is present, there is no upper limit; if the second number and the comma are both omitted, the quantifier specifies an exact number of required matches. Thus .sp [aeiou]{3,} .sp matches at least 3 successive vowels, but may match many more, while .sp \ed{8} .sp matches exactly 8 digits. An opening curly bracket that appears in a position where a quantifier is not allowed, or one that does not match the syntax of a quantifier, is taken as a literal character. For example, {,6} is not a quantifier, but a literal string of four characters. .P In UTF modes, quantifiers apply to characters rather than to individual data units. Thus, for example, \ex{100}{2} matches two characters, each of which is represented by a two-byte sequence in a UTF-8 string. Similarly, \eX{3} matches three Unicode extended sequences, each of which may be several data units long (and they may be of different lengths). .P The quantifier {0} is permitted, causing the expression to behave as if the previous item and the quantifier were not present. This may be useful for subpatterns that are referenced as .\" HTML .\" subroutines .\" from elsewhere in the pattern (but see also the section entitled .\" HTML .\" "Defining subpatterns for use by reference only" .\" below). Items other than subpatterns that have a {0} quantifier are omitted from the compiled pattern. .P For convenience, the three most common quantifiers have single-character abbreviations: .sp * is equivalent to {0,} + is equivalent to {1,} ? is equivalent to {0,1} .sp It is possible to construct infinite loops by following a subpattern that can match no characters with a quantifier that has no upper limit, for example: .sp (a?)* .sp Earlier versions of Perl and PCRE used to give an error at compile time for such patterns. However, because there are cases where this can be useful, such patterns are now accepted, but if any repetition of the subpattern does in fact match no characters, the loop is forcibly broken. .P By default, the quantifiers are "greedy", that is, they match as much as possible (up to the maximum number of permitted times), without causing the rest of the pattern to fail. The classic example of where this gives problems is in trying to match comments in C programs. These appear between /* and */ and within the comment, individual * and / characters may appear. An attempt to match C comments by applying the pattern .sp /\e*.*\e*/ .sp to the string .sp /* first comment */ not comment /* second comment */ .sp fails, because it matches the entire string owing to the greediness of the .* item. .P 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 .sp /\e*.*?\e*/ .sp does the right thing with the C comments. The meaning of the various quantifiers is not otherwise changed, just the preferred number of matches. Do not confuse this use of question mark with its use as a quantifier in its own right. Because it has two uses, it can sometimes appear doubled, as in .sp \ed??\ed .sp which matches one digit by preference, but can match two if that is the only way the rest of the pattern matches. .P If the PCRE_UNGREEDY option is set (an option that 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 When a parenthesized subpattern is quantified with a minimum repeat count that is greater than 1 or with a limited maximum, more memory is required for the compiled pattern, in proportion to the size of the minimum or maximum. .P If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent to Perl's /s) is set, thus allowing the dot 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 normally treats such a pattern as though it were preceded by \eA. .P In cases where it is known that the subject string contains no newlines, it is worth setting PCRE_DOTALL in order to obtain this optimization, or alternatively using ^ to indicate anchoring explicitly. .P However, there is one situation where the optimization cannot be used. When .* is inside capturing parentheses that are the subject of a back reference elsewhere in the pattern, a match at the start may fail where a later one succeeds. Consider, for example: .sp (.*)abc\e1 .sp If the subject is "xyz123abc123" the match point is the fourth character. For this reason, such a pattern is not implicitly anchored. .P When a capturing subpattern is repeated, the value captured is the substring that matched the final iteration. For example, after .sp (tweedle[dume]{3}\es*)+ .sp has matched "tweedledum tweedledee" the value of the captured substring is "tweedledee". However, if there are nested capturing subpatterns, the corresponding captured values may have been set in previous iterations. For example, after .sp /(a|(b))+/ .sp matches "aba" the value of the second captured substring is "b". . . .\" HTML .SH "ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS" .rs .sp With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") repetition, failure of what follows normally causes the repeated item to be re-evaluated to see if a different number of repeats allows the rest of the pattern to match. Sometimes it is useful to prevent this, either to change the nature of the match, or to cause it fail earlier than it otherwise might, when the author of the pattern knows there is no point in carrying on. .P Consider, for example, the pattern \ed+foo when applied to the subject line .sp 123456bar .sp After matching all 6 digits and then failing to match "foo", the normal action of the matcher is to try again with only 5 digits matching the \ed+ item, and then with 4, and so on, before ultimately failing. "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides the means for specifying that once a subpattern has matched, it is not to be re-evaluated in this way. .P If we use atomic grouping for the previous example, the matcher gives up immediately on failing to match "foo" the first time. The notation is a kind of special parenthesis, starting with (?> as in this example: .sp (?>\ed+)foo .sp This kind of parenthesis "locks up" the part of the pattern it contains once it has matched, and a failure further into the pattern is prevented from backtracking into it. Backtracking past it to previous items, however, works as normal. .P An alternative description is that a subpattern of this type matches the string of characters that an identical standalone pattern would match, if anchored at the current point in the subject string. .P Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as the above example can be thought of as a maximizing repeat that must swallow everything it can. So, while both \ed+ and \ed+? are prepared to adjust the number of digits they match in order to make the rest of the pattern match, (?>\ed+) can only match an entire sequence of digits. .P Atomic groups in general can of course contain arbitrarily complicated subpatterns, and can be nested. However, when the subpattern for an atomic group is just a single repeated item, as in the example above, a simpler notation, called a "possessive quantifier" can be used. This consists of an additional + character following a quantifier. Using this notation, the previous example can be rewritten as .sp \ed++foo .sp Note that a possessive quantifier can be used with an entire group, for example: .sp (abc|xyz){2,3}+ .sp Possessive quantifiers are always greedy; the setting of the PCRE_UNGREEDY option is ignored. They are a convenient notation for the simpler forms of atomic group. However, there is no difference in the meaning of a possessive quantifier and the equivalent atomic group, though there may be a performance difference; possessive quantifiers should be slightly faster. .P The possessive quantifier syntax is an extension to the Perl 5.8 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. It ultimately found its way into Perl at release 5.10. .P PCRE has an optimization that automatically "possessifies" certain simple pattern constructs. For example, the sequence A+B is treated as A++B because there is no point in backtracking into a sequence of A's when B must follow. .P When a pattern contains an unlimited repeat inside a subpattern that can itself be repeated an unlimited number of times, the use of an atomic group is the only way to avoid some failing matches taking a very long time indeed. The pattern .sp (\eD+|<\ed+>)*[!?] .sp matches an unlimited number of substrings that either consist of non-digits, or digits enclosed in <>, followed by either ! or ?. When it matches, it runs quickly. However, if it is applied to .sp aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa .sp it takes a long time before reporting failure. This is because the string can be divided between the internal \eD+ repeat and the external * repeat in a large number of ways, and all have to be tried. (The example uses [!?] rather than a single character at the end, because both PCRE and Perl have an optimization that allows for fast failure when a single character is used. They remember the last single character that is required for a match, and fail early if it is not present in the string.) If the pattern is changed so that it uses an atomic group, like this: .sp ((?>\eD+)|<\ed+>)*[!?] .sp sequences of non-digits cannot be broken, and failure happens quickly. . . .\" HTML .SH "BACK REFERENCES" .rs .sp Outside a character class, a backslash followed by a digit greater than 0 (and possibly further digits) is a back reference to a capturing subpattern earlier (that is, to its left) in the pattern, provided there have been that many previous capturing left parentheses. .P However, if the decimal number following the backslash is less than 10, 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 pattern. In other words, the parentheses that are referenced need not be 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 iteration. .P It is not possible to have a numerical "forward back reference" to a subpattern whose number is 10 or more using this syntax because a sequence such as \e50 is interpreted as a character defined in octal. See the subsection entitled "Non-printing characters" .\" HTML .\" above .\" for further details of the handling of digits following a backslash. There is no such problem when named parentheses are used. A back reference to any subpattern is possible using named parentheses (see below). .P Another way of avoiding the ambiguity inherent in the use of digits following a backslash is to use the \eg escape sequence. This escape must be followed by an unsigned number or a negative number, optionally enclosed in braces. These examples are all identical: .sp (ring), \e1 (ring), \eg1 (ring), \eg{1} .sp An unsigned number specifies an absolute reference without the ambiguity that is present in the older syntax. It is also useful when literal digits follow the reference. A negative number is a relative reference. Consider this example: .sp (abc(def)ghi)\eg{-1} .sp The sequence \eg{-1} is a reference to the most recently started capturing subpattern before \eg, that is, is it equivalent to \e2 in this example. Similarly, \eg{-2} would be equivalent to \e1. The use of relative references can be helpful in long patterns, and also in patterns that are created by joining together fragments that contain references within themselves. .P A back reference matches whatever actually matched the capturing subpattern in the current subject string, rather than anything matching the subpattern itself (see .\" HTML .\" "Subpatterns as subroutines" .\" below for a way of doing that). So the pattern .sp (sens|respons)e and \e1ibility .sp 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 example, .sp ((?i)rah)\es+\e1 .sp matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original capturing subpattern is matched caselessly. .P There are several different ways of writing back references to named subpatterns. The .NET syntax \ek{name} and the Perl syntax \ek or \ek'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified back reference syntax, in which \eg can be used for both numeric and named references, is also supported. We could rewrite the above example in any of the following ways: .sp (?(?i)rah)\es+\ek (?'p1'(?i)rah)\es+\ek{p1} (?P(?i)rah)\es+(?P=p1) (?(?i)rah)\es+\eg{p1} .sp A subpattern that is referenced by name may appear in the pattern before or after the reference. .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, any back references to it always fail by default. For example, the pattern .sp (a|(bc))\e2 .sp always fails if it starts to match "a" rather than "bc". However, if the PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back reference to an unset value matches an empty string. .P Because there may be many capturing parentheses in a pattern, all digits following a backslash are taken as part of a potential back reference number. If the pattern continues with a digit character, some delimiter must be used to terminate the back reference. If the PCRE_EXTENDED option is set, this can be white space. Otherwise, the \eg{ syntax or an empty comment (see .\" HTML .\" "Comments" .\" below) can be used. . .SS "Recursive back references" .rs .sp A back reference that occurs inside the parentheses to which it refers fails when the subpattern is first used, so, for example, (a\e1) never matches. However, such references can be useful inside repeated subpatterns. For example, the pattern .sp (a|b\e1)+ .sp matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of the subpattern, the back reference matches the character string corresponding to the previous iteration. In order for this to work, the pattern must be such that the first iteration does not need to match the back reference. This can be done using alternation, as in the example above, or by a quantifier with a minimum of zero. .P Back references of this type cause the group that they reference to be treated as an .\" HTML .\" atomic group. .\" Once the whole group has been matched, a subsequent matching failure cannot cause backtracking into the middle of the group. . . .\" HTML .SH ASSERTIONS .rs .sp An assertion is a test on the characters following or preceding the current matching point that does not actually consume any characters. The simple assertions coded as \eb, \eB, \eA, \eG, \eZ, \ez, ^ and $ are described .\" HTML .\" above. .\" .P More complicated assertions are coded as subpatterns. There are two kinds: those that look ahead of the current position in the subject string, and those that look behind it. An assertion subpattern is matched in the normal way, except that it does not cause the current matching position to be changed. .P Assertion subpatterns are not capturing subpatterns. If such an assertion contains capturing subpatterns within it, these are counted for the purposes of numbering the capturing subpatterns in the whole pattern. However, substring capturing is carried out only for positive assertions, because it does not make sense for negative assertions. .P For compatibility with Perl, assertion subpatterns may be repeated; though it makes no sense to assert the same thing several times, the side effect of capturing parentheses may occasionally be useful. In practice, there only three cases: .sp (1) If the quantifier is {0}, the assertion is never obeyed during matching. However, it may contain internal capturing parenthesized groups that are called from elsewhere via the .\" HTML .\" subroutine mechanism. .\" .sp (2) If quantifier is {0,n} where n is greater than zero, it is treated as if it were {0,1}. At run time, the rest of the pattern match is tried with and without the assertion, the order depending on the greediness of the quantifier. .sp (3) If the minimum repetition is greater than zero, the quantifier is ignored. The assertion is obeyed just once when encountered during matching. . . .SS "Lookahead assertions" .rs .sp Lookahead assertions start with (?= for positive assertions and (?! for negative assertions. For example, .sp \ew+(?=;) .sp matches a word followed by a semicolon, but does not include the semicolon in the match, and .sp foo(?!bar) .sp matches any occurrence of "foo" that is not followed by "bar". Note that the apparently similar pattern .sp (?!foo)bar .sp does not find an occurrence of "bar" that is preceded by something other than "foo"; it finds any occurrence of "bar" whatsoever, because the assertion (?!foo) is always true when the next three characters are "bar". A lookbehind assertion is needed to achieve the other effect. .P If you want to force a matching failure at some point in a pattern, the most convenient way to do it is with (?!) because an empty string always matches, so an assertion that requires there not to be an empty string must always fail. The backtracking control verb (*FAIL) or (*F) is a synonym for (?!). . . .\" HTML .SS "Lookbehind assertions" .rs .sp Lookbehind assertions start with (?<= for positive assertions and (? .\" (see above) .\" can be used instead of a lookbehind assertion to get round the fixed-length restriction. .P The implementation of lookbehind assertions is, for each alternative, to temporarily move the current position back by the fixed length and then try to match. If there are insufficient characters before the current position, the assertion fails. .P In a UTF mode, PCRE does not allow the \eC escape (which matches a single data unit even in a UTF mode) to appear in lookbehind assertions, because it makes it impossible to calculate the length of the lookbehind. The \eX and \eR escapes, which can match different numbers of data units, are also not permitted. .P .\" HTML .\" "Subroutine" .\" calls (see below) such as (?2) or (?&X) are permitted in lookbehinds, as long as the subpattern matches a fixed-length string. .\" HTML .\" Recursion, .\" however, is not supported. .P Possessive quantifiers can be used in conjunction with lookbehind assertions to specify efficient matching of fixed-length strings at the end of subject strings. Consider a simple pattern such as .sp abcd$ .sp when applied to a long string that does not match. Because matching proceeds from left to right, PCRE will look for each "a" in the subject and then see if what follows matches the rest of the pattern. If the pattern is specified as .sp ^.*abcd$ .sp 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 .sp ^.*+(?<=abcd) .sp 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. . . .SS "Using multiple assertions" .rs .sp Several assertions (of any sort) may occur in succession. For example, .sp (?<=\ed{3})(? .SH "CONDITIONAL SUBPATTERNS" .rs .sp It is possible to cause the matching process to obey a subpattern conditionally or to choose between two alternative subpatterns, depending on the result of an assertion, or whether a specific capturing subpattern has already been matched. The two possible forms of conditional subpattern are: .sp (?(condition)yes-pattern) (?(condition)yes-pattern|no-pattern) .sp If the condition is satisfied, the yes-pattern is used; otherwise the no-pattern (if present) is used. If there are more than two alternatives in the subpattern, a compile-time error occurs. Each of the two alternatives may itself contain nested subpatterns of any form, including conditional subpatterns; the restriction to two alternatives applies only at the level of the condition. This pattern fragment is an example where the alternatives are complex: .sp (?(1) (A|B|C) | (D | (?(2)E|F) | E) ) .sp .P There are four kinds of condition: references to subpatterns, references to recursion, a pseudo-condition called DEFINE, and assertions. . .SS "Checking for a used subpattern by number" .rs .sp If the text between the parentheses consists of a sequence of digits, the condition is true if a capturing subpattern of that number has previously matched. If there is more than one capturing subpattern with the same number (see the earlier .\" .\" HTML .\" section about duplicate subpattern numbers), .\" the condition is true if any of them have matched. An alternative notation is to precede the digits with a plus or minus sign. In this case, the subpattern number is relative rather than absolute. The most recently opened parentheses can be referenced by (?(-1), the next most recent by (?(-2), and so on. Inside loops it can also make sense to refer to subsequent groups. The next parentheses to be opened can be referenced as (?(+1), and so on. (The value zero in any of these forms is not used; it provokes a compile-time error.) .P 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: .sp ( \e( )? [^()]+ (?(1) \e) ) .sp The first part matches an optional opening parenthesis, and if that character is present, sets it as the first captured substring. The second part matches one or more characters that are not parentheses. The third part is a conditional subpattern that tests whether or not the first set of parentheses matched. If they did, that is, if subject started with an opening parenthesis, the condition is true, and so the yes-pattern 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. .P If you were embedding this pattern in a larger one, you could use a relative reference: .sp ...other stuff... ( \e( )? [^()]+ (?(-1) \e) ) ... .sp This makes the fragment independent of the parentheses in the larger pattern. . .SS "Checking for a used subpattern by name" .rs .sp Perl uses the syntax (?()...) or (?('name')...) to test for a used subpattern by name. For compatibility with earlier versions of PCRE, which had this facility before Perl, the syntax (?(name)...) is also recognized. However, there is a possible ambiguity with this syntax, because subpattern names may consist entirely of digits. PCRE looks first for a named subpattern; if it cannot find one and the name consists entirely of digits, PCRE looks for a subpattern of that number, which must be greater than zero. Using subpattern names that consist entirely of digits is not recommended. .P Rewriting the above example to use a named subpattern gives this: .sp (? \e( )? [^()]+ (?() \e) ) .sp If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them has matched. . .SS "Checking for pattern recursion" .rs .sp If the condition is the string (R), and there is no subpattern with the name R, the condition is true if a recursive call to the whole pattern or any subpattern has been made. If digits or a name preceded by ampersand follow the letter R, for example: .sp (?(R3)...) or (?(R&name)...) .sp the condition is true if the most recent recursion is into a subpattern whose number or name is given. This condition does not check the entire recursion stack. If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them is the most recent recursion. .P At "top level", all these recursion test conditions are false. .\" HTML .\" The syntax for recursive patterns .\" is described below. . .\" HTML .SS "Defining subpatterns for use by reference only" .rs .sp If the condition is the string (DEFINE), and there is no subpattern with the name DEFINE, the condition is always false. In this case, there may be only one alternative in the subpattern. It is always skipped if control reaches this point in the pattern; the idea of DEFINE is that it can be used to define subroutines that can be referenced from elsewhere. (The use of .\" HTML .\" subroutines .\" is described below.) For example, a pattern to match an IPv4 address such as "192.168.23.245" could be written like this (ignore white space and line breaks): .sp (?(DEFINE) (? 2[0-4]\ed | 25[0-5] | 1\ed\ed | [1-9]?\ed) ) \eb (?&byte) (\e.(?&byte)){3} \eb .sp The first part of the pattern is a DEFINE group inside which a another group named "byte" is defined. This matches an individual component of an IPv4 address (a number less than 256). When matching takes place, this part of the pattern is skipped because DEFINE acts like a false condition. The rest of the pattern uses references to the named group to match the four dot-separated components of an IPv4 address, insisting on a word boundary at each end. . .SS "Assertion conditions" .rs .sp If the condition is not in any of the above formats, it must be an assertion. This may be a positive or negative lookahead or lookbehind assertion. Consider this pattern, again containing non-significant white space, and with the two alternatives on the second line: .sp (?(?=[^a-z]*[a-z]) \ed{2}-[a-z]{3}-\ed{2} | \ed{2}-\ed{2}-\ed{2} ) .sp The condition is a positive lookahead assertion that matches an optional sequence of non-letters followed by a letter. In other words, it tests for the presence of at least one letter in the subject. If a letter is found, the subject is matched against the first alternative; otherwise it is matched against the second. This pattern matches strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits. . . .\" HTML .SH COMMENTS .rs .sp There are two ways of including comments in patterns that are processed by PCRE. In both cases, the start of the comment must not be in a character class, nor in the middle of any other sequence of related characters such as (?: or a subpattern name or number. The characters that make up a comment play no part in the pattern matching. .P The sequence (?# marks the start of a comment that continues up to the next closing parenthesis. Nested parentheses are not permitted. If the PCRE_EXTENDED option is set, an unescaped # character also introduces a comment, which in this case continues to immediately after the next newline character or character sequence in the pattern. Which characters are interpreted as newlines is controlled by the options passed to a compiling function or by a special sequence at the start of the pattern, as described in the section entitled .\" HTML .\" "Newline conventions" .\" above. Note that the end of this type of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. For example, consider this pattern when PCRE_EXTENDED is set, and the default newline convention is in force: .sp abc #comment \en still comment .sp On encountering the # character, \fBpcre_compile()\fP skips along, looking for a newline in the pattern. The sequence \en is still literal at this stage, so it does not terminate the comment. Only an actual character with the code value 0x0a (the default newline) does so. . . .\" HTML .SH "RECURSIVE PATTERNS" .rs .sp Consider the problem of matching a string in parentheses, allowing for unlimited nested parentheses. Without the use of recursion, the best that can be done is to use a pattern that matches up to some fixed depth of nesting. It is not possible to handle an arbitrary nesting depth. .P For some time, Perl has provided a facility that allows regular expressions to recurse (amongst other things). It does this by interpolating Perl code in the expression at run time, and the code can refer to the expression itself. A Perl pattern using code interpolation to solve the parentheses problem can be created like this: .sp $re = qr{\e( (?: (?>[^()]+) | (?p{$re}) )* \e)}x; .sp The (?p{...}) item interpolates Perl code at run time, and in this case refers recursively to the pattern in which it appears. .P Obviously, PCRE cannot support the interpolation of Perl code. Instead, it supports special syntax for recursion of the entire pattern, and also for individual subpattern recursion. After its introduction in PCRE and Python, this kind of recursion was subsequently introduced into Perl at release 5.10. .P A special item that consists of (? followed by a number greater than zero and a closing parenthesis is a recursive subroutine call of the subpattern of the given number, provided that it occurs inside that subpattern. (If not, it is a .\" HTML .\" non-recursive subroutine .\" call, which is described in the next section.) The special item (?R) or (?0) is a recursive call of the entire regular expression. .P This PCRE pattern solves the nested parentheses problem (assume the PCRE_EXTENDED option is set so that white space is ignored): .sp \e( ( [^()]++ | (?R) )* \e) .sp First it matches an opening parenthesis. Then it matches any number of substrings which can either be a sequence of non-parentheses, or a recursive match of the pattern itself (that is, a correctly parenthesized substring). Finally there is a closing parenthesis. Note the use of a possessive quantifier to avoid backtracking into sequences of non-parentheses. .P If this were part of a larger pattern, you would not want to recurse the entire pattern, so instead you could use this: .sp ( \e( ( [^()]++ | (?1) )* \e) ) .sp We have put the pattern into parentheses, and caused the recursion to refer to them instead of the whole pattern. .P In a larger pattern, keeping track of parenthesis numbers can be tricky. This is made easier by the use of relative references. Instead of (?1) in the pattern above you can write (?-2) to refer to the second most recently opened parentheses preceding the recursion. In other words, a negative number counts capturing parentheses leftwards from the point at which it is encountered. .P It is also possible to refer to subsequently opened parentheses, by writing references such as (?+2). However, these cannot be recursive because the reference is not inside the parentheses that are referenced. They are always .\" HTML .\" non-recursive subroutine .\" calls, as described in the next section. .P An alternative approach is to use named parentheses instead. The Perl syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also supported. We could rewrite the above example as follows: .sp (? \e( ( [^()]++ | (?&pn) )* \e) ) .sp If there is more than one subpattern with the same name, the earliest one is used. .P This particular example pattern that we have been looking at contains nested unlimited repeats, and so the use of a possessive quantifier for matching strings of non-parentheses is important when applying the pattern to strings that do not match. For example, when this pattern is applied to .sp (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() .sp it yields "no match" quickly. However, if a possessive quantifier is not used, the match runs for a very long time indeed because there are so many different ways the + and * repeats can carve up the subject, and all have to be tested before failure can be reported. .P At the end of a match, the values of capturing parentheses are those from the outermost level. If you want to obtain intermediate values, a callout function can be used (see below and the .\" HREF \fBpcrecallout\fP .\" documentation). If the pattern above is matched against .sp (ab(cd)ef) .sp the value for the inner capturing parentheses (numbered 2) is "ef", which is the last value taken on at the top level. If a capturing subpattern is not matched at the top level, its final captured value is unset, even if it was (temporarily) set at a deeper level during the matching process. .P 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\fP, freeing it via \fBpcre_free\fP afterwards. If no memory can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error. .P Do not confuse the (?R) item with the condition (R), which tests for recursion. Consider this pattern, which matches text in angle brackets, allowing for arbitrary nesting. Only digits are allowed in nested brackets (that is, when recursing), whereas any characters are permitted at the outer level. .sp < (?: (?(R) \ed++ | [^<>]*+) | (?R)) * > .sp In this pattern, (?(R) is the start of a conditional subpattern, with two different alternatives for the recursive and non-recursive cases. The (?R) item is the actual recursive call. . . .\" HTML .SS "Differences in recursion processing between PCRE and Perl" .rs .sp Recursion processing in PCRE differs from Perl in two important ways. In PCRE (like Python, but unlike Perl), a recursive subpattern 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 there is a subsequent matching failure. This can be illustrated by the following pattern, which purports to match a palindromic string that contains an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"): .sp ^(.|(.)(?1)\e2)$ .sp The idea is that it either matches a single character, or two identical characters surrounding a sub-palindrome. In Perl, this pattern works; in PCRE it does not if the pattern is longer than three characters. Consider the subject string "abcba": .P At the top level, the first character is matched, but as it is not at the end of the string, the first alternative fails; the second alternative is taken and the recursion kicks in. The recursive call to subpattern 1 successfully matches the next character ("b"). (Note that the beginning and end of line tests are not part of the recursion). .P Back at the top level, the next character ("c") is compared with what subpattern 2 matched, which was "a". This fails. Because the recursion is treated as an atomic group, there are now no backtracking points, and so the entire match fails. (Perl is able, at this point, to re-enter the recursion and try the second alternative.) However, if the pattern is written with the alternatives in the other order, things are different: .sp ^((.)(?1)\e2|.)$ .sp This time, the recursing alternative is tried first, and continues to recurse until it runs out of characters, at which point the recursion fails. But this time we do have another alternative to try at the higher level. That is the big difference: in the previous case the remaining alternative is at a deeper recursion level, which PCRE cannot use. .P To change the pattern so that it matches all palindromic strings, not just those with an odd number of characters, it is tempting to change the pattern to this: .sp ^((.)(?1)\e2|.?)$ .sp Again, this works in Perl, but not in PCRE, and for the same reason. When a deeper recursion has matched a single character, it cannot be entered again in order to match an empty string. The solution is to separate the two cases, and write out the odd and even cases as alternatives at the higher level: .sp ^(?:((.)(?1)\e2|)|((.)(?3)\e4|.)) .sp If you want to match typical palindromic phrases, the pattern has to ignore all non-word characters, which can be done like this: .sp ^\eW*+(?:((.)\eW*+(?1)\eW*+\e2|)|((.)\eW*+(?3)\eW*+\e4|\eW*+.\eW*+))\eW*+$ .sp If run with the PCRE_CASELESS option, this pattern matches phrases such as "A man, a plan, a canal: Panama!" and it works well in both PCRE and Perl. Note the use of the possessive quantifier *+ to avoid backtracking into sequences of non-word characters. Without this, PCRE takes a great deal longer (ten times or more) to match typical phrases, and Perl takes so long that you think it has gone into a loop. .P \fBWARNING\fP: The palindrome-matching patterns above work only if the subject string does not start with a palindrome that is shorter than the entire string. For example, although "abcba" is correctly matched, if the subject is "ababa", PCRE finds the palindrome "aba" at the start, then fails at top level because the end of the string does not follow. Once again, it cannot jump back into the recursion to try other alternatives, so the entire match fails. .P The second way in which PCRE and Perl differ in their recursion processing is in the handling of captured values. In Perl, when a subpattern is called recursively or as a subpattern (see the next section), it has no access to any values that were captured outside the recursion, whereas in PCRE these values can be referenced. Consider this pattern: .sp ^(.)(\e1|a(?2)) .sp In PCRE, this pattern matches "bab". The first capturing parentheses match "b", then in the second group, when the back reference \e1 fails to match "b", the second alternative matches "a" and then recurses. In the recursion, \e1 does now match "b" and so the whole match succeeds. In Perl, the pattern fails to match because inside the recursive call \e1 cannot access the externally set value. . . .\" HTML .SH "SUBPATTERNS AS SUBROUTINES" .rs .sp If the syntax for a recursive subpattern call (either by number or by name) is used outside the parentheses to which it refers, it operates like a subroutine in a programming language. The called subpattern may be defined before or after the reference. A numbered reference can be absolute or relative, as in these examples: .sp (...(absolute)...)...(?2)... (...(relative)...)...(?-1)... (...(?+1)...(relative)... .sp An earlier example pointed out that the pattern .sp (sens|respons)e and \e1ibility .sp matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility". If instead the pattern .sp (sens|respons)e and (?1)ibility .sp is used, it does match "sense and responsibility" as well as the other two strings. Another example is given in the discussion of DEFINE above. .P All subroutine calls, whether recursive or not, are always treated as atomic groups. That is, once a subroutine 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. Any capturing parentheses that are set during the subroutine call revert to their previous values afterwards. .P Processing options such as case-independence are fixed when a subpattern is defined, so if it is used as a subroutine, such options cannot be changed for different calls. For example, consider this pattern: .sp (abc)(?i:(?-1)) .sp It matches "abcabc". It does not match "abcABC" because the change of processing option does not affect the called subpattern. . . .\" HTML .SH "ONIGURUMA SUBROUTINE SYNTAX" .rs .sp For compatibility with Oniguruma, the non-Perl syntax \eg followed by a name or a number enclosed either in angle brackets or single quotes, is an alternative syntax for referencing a subpattern as a subroutine, possibly recursively. Here are two of the examples used above, rewritten using this syntax: .sp (? \e( ( (?>[^()]+) | \eg )* \e) ) (sens|respons)e and \eg'1'ibility .sp PCRE supports an extension to Oniguruma: if a number is preceded by a plus or a minus sign it is taken as a relative reference. For example: .sp (abc)(?i:\eg<-1>) .sp Note that \eg{...} (Perl syntax) and \eg<...> (Oniguruma syntax) are \fInot\fP synonymous. The former is a back reference; the latter is a subroutine call. . . .SH CALLOUTS .rs .sp Perl has a feature whereby using the sequence (?{...}) causes arbitrary Perl code to be obeyed in the middle of matching a regular expression. This makes it possible, amongst other things, to extract different substrings that match the same pair of parentheses when there is a repetition. .P 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 \fIpcre_callout\fP (8-bit library) or \fIpcre16_callout\fP (16-bit library). By default, this variable contains NULL, which disables all calling out. .P 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: .sp (?C1)abc(?C2)def .sp If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, callouts are automatically installed before each item in the pattern. They are all numbered 255. .P During matching, when PCRE reaches a callout point, 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 the matching function. The callout function may cause matching to proceed, to backtrack, or to fail altogether. A complete description of the interface to the callout function is given in the .\" HREF \fBpcrecallout\fP .\" documentation. . . .\" HTML .SH "BACKTRACKING CONTROL" .rs .sp Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which are described in the Perl documentation as "experimental and subject to change or removal in a future version of Perl". It goes on to say: "Their usage in production code should be noted to avoid problems during upgrades." The same remarks apply to the PCRE features described in this section. .P Since these verbs are specifically related to backtracking, most of them can be used only when the pattern is to be matched using one of the traditional matching functions, which use a backtracking algorithm. With the exception of (*FAIL), which behaves like a failing negative assertion, they cause an error if encountered by a DFA matching function. .P If any of these verbs are used in an assertion or in a subpattern that is called as a subroutine (whether or not recursively), their effect is confined to that subpattern; it does not extend to the surrounding pattern, with one exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a successful positive assertion \fIis\fP passed back when a match succeeds (compare capturing parentheses in assertions). Note that such subpatterns are processed as anchored at the point where they are tested. Note also that Perl's treatment of subroutines and assertions is different in some cases. .P The new verbs make use of what was previously invalid syntax: an opening parenthesis followed by an asterisk. They are generally of the form (*VERB) or (*VERB:NAME). Some may take either form, with differing behaviour, depending on whether or not an argument is present. A name is any sequence of characters that does not include a closing parenthesis. The maximum length of name is 255 in the 8-bit library and 65535 in the 16-bit library. If the name is empty, that is, if the closing parenthesis immediately follows the colon, the effect is as if the colon were not there. Any number of these verbs may occur in a pattern. . . .\" HTML .SS "Optimizations that affect backtracking verbs" .rs .sp PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it may know the minimum length of matching subject, or that a particular character must be present. When one of these optimizations suppresses the running of a match, any included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling \fBpcre_compile()\fP or \fBpcre_exec()\fP, or by starting the pattern with (*NO_START_OPT). There is more discussion of this option in the section entitled .\" HTML .\" "Option bits for \fBpcre_exec()\fP" .\" in the .\" HREF \fBpcreapi\fP .\" documentation. .P Experiments with Perl suggest that it too has similar optimizations, sometimes leading to anomalous results. . . .SS "Verbs that act immediately" .rs .sp The following verbs act as soon as they are encountered. They may not be followed by a name. .sp (*ACCEPT) .sp This verb causes the match to end successfully, skipping the remainder of the pattern. However, when it is inside a subpattern that is called as a subroutine, only that subpattern is ended successfully. Matching then continues at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so far is captured. For example: .sp A((?:A|B(*ACCEPT)|C)D) .sp This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is captured by the outer parentheses. .sp (*FAIL) or (*F) .sp This verb causes a matching failure, forcing backtracking to occur. It is equivalent to (?!) but easier to read. The Perl documentation notes that it is probably useful only when combined with (?{}) or (??{}). Those are, of course, Perl features that are not present in PCRE. The nearest equivalent is the callout feature, as for example in this pattern: .sp a+(?C)(*FAIL) .sp A match with the string "aaaa" always fails, but the callout is taken before each backtrack happens (in this example, 10 times). . . .SS "Recording which path was taken" .rs .sp There is one verb whose main purpose is to track how a match was arrived at, though it also has a secondary use in conjunction with advancing the match starting point (see (*SKIP) below). .sp (*MARK:NAME) or (*:NAME) .sp A name is always required with this verb. There may be as many instances of (*MARK) as you like in a pattern, and their names do not have to be unique. .P When a match succeeds, the name of the last-encountered (*MARK) on the matching path is passed back to the caller as described in the section entitled .\" HTML .\" "Extra data for \fBpcre_exec()\fP" .\" in the .\" HREF \fBpcreapi\fP .\" documentation. Here is an example of \fBpcretest\fP output, where the /K modifier requests the retrieval and outputting of (*MARK) data: .sp re> /X(*MARK:A)Y|X(*MARK:B)Z/K data> XY 0: XY MK: A XZ 0: XZ MK: B .sp The (*MARK) name is tagged with "MK:" in this output, and in this example it indicates which of the two alternatives matched. This is a more efficient way of obtaining this information than putting each alternative in its own capturing parentheses. .P If (*MARK) is encountered in a positive assertion, its name is recorded and passed back if it is the last-encountered. This does not happen for negative assertions. .P After a partial match or a failed match, the name of the last encountered (*MARK) in the entire match process is returned. For example: .sp re> /X(*MARK:A)Y|X(*MARK:B)Z/K data> XP No match, mark = B .sp Note that in this unanchored example the mark is retained from the match attempt that started at the letter "X" in the subject. Subsequent match attempts starting at "P" and then with an empty string do not get as far as the (*MARK) item, but nevertheless do not reset it. .P If you are interested in (*MARK) values after failed matches, you should probably set the PCRE_NO_START_OPTIMIZE option .\" HTML .\" (see above) .\" to ensure that the match is always attempted. . . .SS "Verbs that act after backtracking" .rs .sp The following verbs do nothing when they are encountered. Matching continues with what follows, but if there is no subsequent match, causing a backtrack to the verb, a failure is forced. That is, backtracking cannot pass to the left of the verb. However, when one of these verbs appears inside an atomic group, its effect is confined to that group, because once the group has been matched, there is never any backtracking into it. In this situation, backtracking can "jump back" to the left of the entire atomic group. (Remember also, as stated above, that this localization also applies in subroutine calls and assertions.) .P These verbs differ in exactly what kind of failure occurs when backtracking reaches them. .sp (*COMMIT) .sp This verb, which may not be followed by a name, causes the whole match to fail outright if the rest of the pattern does not match. Even if the pattern is unanchored, no further attempts to find a match by advancing the starting point take place. Once (*COMMIT) has been passed, \fBpcre_exec()\fP is committed to finding a match at the current starting point, or not at all. For example: .sp a+(*COMMIT)b .sp This matches "xxaab" but not "aacaab". It can be thought of as a kind of dynamic anchor, or "I've started, so I must finish." The name of the most recently passed (*MARK) in the path is passed back when (*COMMIT) forces a match failure. .P Note that (*COMMIT) at the start of a pattern is not the same as an anchor, unless PCRE's start-of-match optimizations are turned off, as shown in this \fBpcretest\fP example: .sp re> /(*COMMIT)abc/ data> xyzabc 0: abc xyzabc\eY No match .sp PCRE knows that any match must start with "a", so the optimization skips along the subject to "a" before running the first match attempt, which succeeds. When the optimization is disabled by the \eY escape in the second subject, the match starts at "x" and so the (*COMMIT) causes it to fail without trying any other starting points. .sp (*PRUNE) or (*PRUNE:NAME) .sp This verb causes the match to fail at the current starting position in the subject if the rest of the pattern does not match. If the pattern is unanchored, the normal "bumpalong" advance to the next starting character then happens. Backtracking can occur as usual to the left of (*PRUNE), before it is reached, or when matching to the right of (*PRUNE), but if there is no match to the right, backtracking cannot cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alternative to an atomic group or possessive quantifier, but there are some uses of (*PRUNE) that cannot be expressed in any other way. The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an anchored pattern (*PRUNE) has the same effect as (*COMMIT). .sp (*SKIP) .sp This verb, when given without a name, is like (*PRUNE), except that if the pattern is unanchored, the "bumpalong" advance is not to the next character, but to the position in the subject where (*SKIP) was encountered. (*SKIP) signifies that whatever text was matched leading up to it cannot be part of a successful match. Consider: .sp a+(*SKIP)b .sp If the subject is "aaaac...", after the first match attempt fails (starting at the first character in the string), the starting point skips on to start the next attempt at "c". Note that a possessive quantifer does not have the same effect as this example; although it would suppress backtracking during the first match attempt, the second attempt would start at the second character instead of skipping on to "c". .sp (*SKIP:NAME) .sp When (*SKIP) has an associated name, its behaviour is modified. If the following pattern fails to match, the previous path through the pattern is searched for the most recent (*MARK) that has the same name. If one is found, the "bumpalong" advance is to the subject position that corresponds to that (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a matching name is found, the (*SKIP) is ignored. .sp (*THEN) or (*THEN:NAME) .sp This verb causes a skip to the next innermost alternative if the rest of the pattern does not match. That is, it cancels pending backtracking, but only within the current alternative. Its name comes from the observation that it can be used for a pattern-based if-then-else block: .sp ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ... .sp If the COND1 pattern matches, FOO is tried (and possibly further items after the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking into COND1. The behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts like (*PRUNE). .P Note that a subpattern that does not contain a | character is just a part of the enclosing alternative; it is not a nested alternation with only one alternative. The effect of (*THEN) extends beyond such a subpattern to the enclosing alternative. Consider this pattern, where A, B, etc. are complex pattern fragments that do not contain any | characters at this level: .sp A (B(*THEN)C) | D .sp If A and B are matched, but there is a failure in C, matching does not backtrack into A; instead it moves to the next alternative, that is, D. However, if the subpattern containing (*THEN) is given an alternative, it behaves differently: .sp A (B(*THEN)C | (*FAIL)) | D .sp The effect of (*THEN) is now confined to the inner subpattern. After a failure in C, matching moves to (*FAIL), which causes the whole subpattern to fail because there are no more alternatives to try. In this case, matching does now backtrack into A. .P Note also that a conditional subpattern is not considered as having two alternatives, because only one is ever used. In other words, the | character in a conditional subpattern has a different meaning. Ignoring white space, consider: .sp ^.*? (?(?=a) a | b(*THEN)c ) .sp If the subject is "ba", this pattern does not match. Because .*? is ungreedy, it initially matches zero characters. The condition (?=a) then fails, the character "b" is matched, but "c" is not. At this point, matching does not backtrack to .*? as might perhaps be expected from the presence of the | character. The conditional subpattern is part of the single alternative that comprises the whole pattern, and so the match fails. (If there was a backtrack into .*?, allowing it to match "b", the match would succeed.) .P The verbs just described provide four different "strengths" of control when subsequent matching fails. (*THEN) is the weakest, carrying on the match at the next alternative. (*PRUNE) comes next, failing the match at the current starting position, but allowing an advance to the next character (for an unanchored pattern). (*SKIP) is similar, except that the advance may be more than one character. (*COMMIT) is the strongest, causing the entire match to fail. .P If more than one such verb is present in a pattern, the "strongest" one wins. For example, consider this pattern, where A, B, etc. are complex pattern fragments: .sp (A(*COMMIT)B(*THEN)C|D) .sp Once A has matched, PCRE is committed to this match, at the current starting position. If subsequently B matches, but C does not, the normal (*THEN) action of trying the next alternative (that is, D) does not happen because (*COMMIT) overrides. . . .SH "SEE ALSO" .rs .sp \fBpcreapi\fP(3), \fBpcrecallout\fP(3), \fBpcrematching\fP(3), \fBpcresyntax\fP(3), \fBpcre\fP(3), \fBpcre16(3)\fP. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 17 June 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_pattern_to_host_byte_order.30000644000222100022210000000235311735631612016607 00000000000000.TH PCRE_PATTERN_TO_HOST_BYTE_ORDER 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_pattern_to_host_byte_order(pcre *\fIcode\fP, .ti +5n .B pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP); .PP .B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP, .ti +5n .B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP); . . .SH DESCRIPTION .rs .sp This function ensures that the bytes in 2-byte and 4-byte values in a compiled pattern are in the correct order for the current host. It is useful when a pattern that has been compiled on one host is transferred to another that might have different endianness. The arguments are: .sp \fIcode\fP A compiled regular expression \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure, or is NULL \fItables\fP Pointer to character tables, or NULL to set the built-in default .sp The result is 0 for success, a negative PCRE_ERROR_xxx value otherwise. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcretest.txt0000644000222100022210000012704711775533017012466 00000000000000PCRETEST(1) PCRETEST(1) NAME pcretest - a program for testing Perl-compatible regular expressions. SYNOPSIS pcretest [options] [input file [output file]] pcretest was written as a test program for the PCRE regular expression library itself, but it can also be used for experimenting with regular expressions. This document describes the features of the test program; for details of the regular expressions themselves, see the pcrepattern documentation. For details of the PCRE library function calls and their options, see the pcreapi and pcre16 documentation. The input for pcretest is a sequence of regular expression patterns and strings to be matched, as described below. The output shows the result of each match. Options on the command line and the patterns control PCRE options and exactly what is output. PCRE's 8-BIT and 16-BIT LIBRARIES From release 8.30, two separate PCRE libraries can be built. The origi- nal one supports 8-bit character strings, whereas the newer 16-bit library supports character strings encoded in 16-bit units. The pcretest program can be used to test both libraries. However, it is itself still an 8-bit program, reading 8-bit input and writing 8-bit output. When testing the 16-bit library, the patterns and data strings are converted to 16-bit format before being passed to the PCRE library functions. Results are converted to 8-bit for output. References to functions and structures of the form pcre[16]_xx below mean "pcre_xx when using the 8-bit library or pcre16_xx when using the 16-bit library". COMMAND LINE OPTIONS -16 If both the 8-bit and the 16-bit libraries have been built, this option causes the 16-bit library to be used. If only the 16-bit library has been built, this is the default (so has no effect). If only the 8-bit library has been built, this option causes an error. -b Behave as if each pattern has the /B (show byte code) modi- fier; the internal form is output after compilation. -C Output the version number of the PCRE library, and all avail- able information about the optional features that are included, and then exit. All other options are ignored. -C option Output information about a specific build-time option, then exit. This functionality is intended for use in scripts such as RunTest. The following options output the value indicated: linksize the internal link size (2, 3, or 4) newline the default newline setting: CR, LF, CRLF, ANYCRLF, or ANY The following options output 1 for true or zero for false: jit just-in-time support is available pcre16 the 16-bit library was built pcre8 the 8-bit library was built ucp Unicode property support is available utf UTF-8 and/or UTF-16 support is available -d Behave as if each pattern has the /D (debug) modifier; the internal form and information about the compiled pattern is output after compilation; -d is equivalent to -b -i. -dfa Behave as if each data line contains the \D escape sequence; this causes the alternative matching function, pcre[16]_dfa_exec(), to be used instead of the standard pcre[16]_exec() function (more detail is given below). -help Output a brief summary these options and then exit. -i Behave as if each pattern has the /I modifier; information about the compiled pattern is given after compilation. -M Behave as if each data line contains the \M escape sequence; this causes PCRE to discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings by calling pcre[16]_exec() repeatedly with different limits. -m Output the size of each compiled pattern after it has been compiled. This is equivalent to adding /M to each regular expression. The size is given in bytes for both libraries. -o osize Set the number of elements in the output vector that is used when calling pcre[16]_exec() or pcre[16]_dfa_exec() to be osize. The default value is 45, which is enough for 14 cap- turing subexpressions for pcre[16]_exec() or 22 different matches for pcre[16]_dfa_exec(). The vector size can be changed for individual matching calls by including \O in the data line (see below). -p Behave as if each pattern has the /P modifier; the POSIX wrapper API is used to call PCRE. None of the other options has any effect when -p is set. This option can be used only with the 8-bit library. -q Do not output the version number of pcretest at the start of execution. -S size On Unix-like systems, set the size of the run-time stack to size megabytes. -s or -s+ Behave as if each pattern has the /S modifier; in other words, force each pattern to be studied. If -s+ is used, all the JIT compile options are passed to pcre[16]_study(), caus- ing just-in-time optimization to be set up if it is avail- able, for both full and partial matching. Specific JIT com- pile options can be selected by following -s+ with a digit in the range 1 to 7, which selects the JIT compile modes as fol- lows: 1 normal match only 2 soft partial match only 3 normal match and soft partial match 4 hard partial match only 6 soft and hard partial match 7 all three modes (default) If -s++ is used instead of -s+ (with or without a following digit), the text "(JIT)" is added to the first output line after a match or no match when JIT-compiled code was actually used. If the /I or /D option is present on a pattern (requesting output about the compiled pattern), information about the result of studying is not included when studying is caused only by -s and neither -i nor -d is present on the command line. This behaviour means that the output from tests that are run with and without -s should be identical, except when options that output information about the actual running of a match are set. The -M, -t, and -tm options, which give information about resources used, are likely to produce different output with and without -s. Out- put may also differ if the /C option is present on an individual pat- tern. This uses callouts to trace the the matching process, and this may be different between studied and non-studied patterns. If the pat- tern contains (*MARK) items there may also be differences, for the same reason. The -s command line option can be overridden for specific pat- terns that should never be studied (see the /S pattern modifier below). -t Run each compile, study, and match many times with a timer, and output resulting time per compile or match (in millisec- onds). Do not set -m with -t, because you will then get the size output a zillion times, and the timing will be dis- torted. You can control the number of iterations that are used for timing by following -t with a number (as a separate item on the command line). For example, "-t 1000" would iter- ate 1000 times. The default is to iterate 500000 times. -tm This is like -t except that it times only the matching phase, not the compile or study phases. DESCRIPTION If pcretest is given two filename arguments, it reads from the first and writes to the second. If it is given only one filename argument, it reads from that file and writes to stdout. Otherwise, it reads from stdin and writes to stdout, and prompts for each line of input, using "re>" to prompt for regular expressions, and "data>" to prompt for data lines. When pcretest is built, a configuration option can specify that it should be linked with the libreadline library. When this is done, if the input is from a terminal, it is read using the readline() function. This provides line-editing and history facilities. The output from the -help option states whether or not readline() will be used. The program handles any number of sets of input on a single input file. Each set starts with a regular expression, and continues with any num- ber of data lines to be matched against the pattern. Each data line is matched separately and independently. If you want to do multi-line matches, you have to use the \n escape sequence (or \r or \r\n, etc., depending on the newline setting) in a single line of input to encode the newline sequences. There is no limit on the length of data lines; the input buffer is automatically extended if it is too small. An empty line signals the end of the data lines, at which point a new regular expression is read. The regular expressions are given enclosed in any non-alphanumeric delimiters other than backslash, for example: /(a|bc)x+yz/ White space before the initial delimiter is ignored. A regular expres- sion may be continued over several input lines, in which case the new- line characters are included within it. It is possible to include the delimiter within the pattern by escaping it, for example /abc\/def/ If you do so, the escape and the delimiter form part of the pattern, but since delimiters are always non-alphanumeric, this does not affect its interpretation. If the terminating delimiter is immediately fol- lowed by a backslash, for example, /abc/\ then a backslash is added to the end of the pattern. This is done to provide a way of testing the error condition that arises if a pattern finishes with a backslash, because /abc\/ is interpreted as the first line of a pattern that starts with "abc/", causing pcretest to read the next line as a continuation of the regular expression. PATTERN MODIFIERS A pattern may be followed by any number of modifiers, which are mostly single characters. Following Perl usage, these are referred to below as, for example, "the /i modifier", even though the delimiter of the pattern need not always be a slash, and no slash is used when writing modifiers. White space may appear between the final pattern delimiter and the first modifier, and between the modifiers themselves. The /i, /m, /s, and /x modifiers set the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when pcre[16]_com- pile() is called. These four modifier letters have the same effect as they do in Perl. For example: /caseless/i The following table shows additional modifiers for setting PCRE com- pile-time options that do not correspond to anything in Perl: /8 PCRE_UTF8 ) when using the 8-bit /? PCRE_NO_UTF8_CHECK ) library /8 PCRE_UTF16 ) when using the 16-bit /? PCRE_NO_UTF16_CHECK ) library /A PCRE_ANCHORED /C PCRE_AUTO_CALLOUT /E PCRE_DOLLAR_ENDONLY /f PCRE_FIRSTLINE /J PCRE_DUPNAMES /N PCRE_NO_AUTO_CAPTURE /U PCRE_UNGREEDY /W PCRE_UCP /X PCRE_EXTRA /Y PCRE_NO_START_OPTIMIZE / PCRE_JAVASCRIPT_COMPAT / PCRE_NEWLINE_CR / PCRE_NEWLINE_LF / PCRE_NEWLINE_CRLF / PCRE_NEWLINE_ANYCRLF / PCRE_NEWLINE_ANY / PCRE_BSR_ANYCRLF / PCRE_BSR_UNICODE The modifiers that are enclosed in angle brackets are literal strings as shown, including the angle brackets, but the letters within can be in either case. This example sets multiline matching with CRLF as the line ending sequence: /^abc/m As well as turning on the PCRE_UTF8/16 option, the /8 modifier causes all non-printing characters in output strings to be printed using the \x{hh...} notation. Otherwise, those less than 0x100 are output in hex without the curly brackets. Full details of the PCRE options are given in the pcreapi documenta- tion. Finding all matches in a string Searching for all possible matches within each subject string can be requested by the /g or /G modifier. After finding a match, PCRE is called again to search the remainder of the subject string. The differ- ence between /g and /G is that the former uses the startoffset argument to pcre[16]_exec() to start searching at a new point within the entire string (which is in effect what Perl does), whereas the latter passes over a shortened substring. This makes a difference to the matching process if the pattern begins with a lookbehind assertion (including \b or \B). If any call to pcre[16]_exec() in a /g or /G sequence matches an empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART 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, and the normal match is retried. This imitates the way Perl handles such cases when using the /g modifier or the split() func- tion. Normally, the start offset is advanced by one character, but if the newline convention recognizes CRLF as a newline, and the current character is CR followed by LF, an advance of two is used. Other modifiers There are yet more modifiers for controlling the way pcretest operates. The /+ modifier requests that as well as outputting the substring that matched the entire pattern, pcretest should in addition output the remainder of the subject string. This is useful for tests where the subject contains multiple copies of the same substring. If the + modi- fier appears twice, the same action is taken for captured substrings. In each case the remainder is output on the following line with a plus character following the capture number. Note that this modifier must not immediately follow the /S modifier because /S+ and /S++ have other meanings. The /= modifier requests that the values of all potential captured parentheses be output after a match. By default, only those up to the highest one actually used in the match are output (corresponding to the return code from pcre[16]_exec()). Values in the offsets vector corre- sponding to higher numbers should be set to -1, and these are output as "". This modifier gives a way of checking that this is happen- ing. The /B modifier is a debugging feature. It requests that pcretest out- put a representation of the compiled code after compilation. Normally this information contains length and offset values; however, if /Z is also present, this data is replaced by spaces. This is a special fea- ture for use in the automatic test scripts; it ensures that the same output is generated for different internal link sizes. The /D modifier is a PCRE debugging feature, and is equivalent to /BI, that is, both the /B and the /I modifiers. The /F modifier causes pcretest to flip the byte order of the 2-byte and 4-byte fields in the compiled pattern. This facility is for testing the feature in PCRE that allows it to execute patterns that were com- piled on a host with a different endianness. This feature is not avail- able when the POSIX interface to PCRE is being used, that is, when the /P pattern modifier is specified. See also the section about saving and reloading compiled patterns below. The /I modifier requests that pcretest output information about the compiled pattern (whether it is anchored, has a fixed first character, and so on). It does this by calling pcre[16]_fullinfo() after compiling a pattern. If the pattern is studied, the results of that are also out- put. The /K modifier requests pcretest to show names from backtracking con- trol verbs that are returned from calls to pcre[16]_exec(). It causes pcretest to create a pcre[16]_extra block if one has not already been created by a call to pcre[16]_study(), and to set the PCRE_EXTRA_MARK flag and the mark field within it, every time that pcre[16]_exec() is called. If the variable that the mark field points to is non-NULL for a match, non-match, or partial match, pcretest prints the string to which it points. For a match, this is shown on a line by itself, tagged with "MK:". For a non-match it is added to the message. The /L modifier must be followed directly by the name of a locale, for example, /pattern/Lfr_FR For this reason, it must be the last modifier. The given locale is set, pcre[16]_maketables() is called to build a set of character tables for the locale, and this is then passed to pcre[16]_compile() when compil- ing the regular expression. Without an /L (or /T) modifier, NULL is passed as the tables pointer; that is, /L applies only to the expres- sion on which it appears. The /M modifier causes the size in bytes of the memory block used to hold the compiled pattern to be output. This does not include the size of the pcre[16] block; it is just the actual compiled data. If the pat- tern is successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the JIT compiled code is also output. If the /S modifier appears once, it causes pcre[16]_study() to be called after the expression has been compiled, and the results used when the expression is matched. If /S appears twice, it suppresses studying, even if it was requested externally by the -s command line option. This makes it possible to specify that certain patterns are always studied, and others are never studied, independently of -s. This feature is used in the test files in a few cases where the output is different when the pattern is studied. If the /S modifier is immediately followed by a + character, the call to pcre[16]_study() is made with all the JIT study options, requesting just-in-time optimization support if it is available, for both normal and partial matching. If you want to restrict the JIT compiling modes, you can follow /S+ with a digit in the range 1 to 7: 1 normal match only 2 soft partial match only 3 normal match and soft partial match 4 hard partial match only 6 soft and hard partial match 7 all three modes (default) If /S++ is used instead of /S+ (with or without a following digit), the text "(JIT)" is added to the first output line after a match or no match when JIT-compiled code was actually used. Note that there is also an independent /+ modifier; it must not be given immediately after /S or /S+ because this will be misinterpreted. If JIT studying is successful, the compiled JIT code will automatically be used when pcre[16]_exec() is run, except when incompatible run-time options are specified. For more details, see the pcrejit documentation. See also the \J escape sequence below for a way of setting the size of the JIT stack. The /T modifier must be followed by a single digit. It causes a spe- cific set of built-in character tables to be passed to pcre[16]_com- pile(). It is used in the standard PCRE tests to check behaviour with different character tables. The digit specifies the tables as follows: 0 the default ASCII tables, as distributed in pcre_chartables.c.dist 1 a set of tables defining ISO 8859 characters In table 1, some characters whose codes are greater than 128 are iden- tified as letters, digits, spaces, etc. Using the POSIX wrapper API The /P modifier causes pcretest to call PCRE via the POSIX wrapper API rather than its native API. This supports only the 8-bit library. When /P is set, the following modifiers set options for the regcomp() func- tion: /i REG_ICASE /m REG_NEWLINE /N REG_NOSUB /s REG_DOTALL ) /U REG_UNGREEDY ) These options are not part of /W REG_UCP ) the POSIX standard /8 REG_UTF8 ) The /+ modifier works as described above. All other modifiers are ignored. DATA LINES Before each data line is passed to pcre[16]_exec(), leading and trail- ing white space is removed, and it is then scanned for \ escapes. Some of these are pretty esoteric features, intended for checking out some of the more complicated features of PCRE. If you are just testing "ordinary" regular expressions, you probably don't need any of these. The following escapes are recognized: \a alarm (BEL, \x07) \b backspace (\x08) \e escape (\x27) \f form feed (\x0c) \n newline (\x0a) \qdd set the PCRE_MATCH_LIMIT limit to dd (any number of digits) \r carriage return (\x0d) \t tab (\x09) \v vertical tab (\x0b) \nnn octal character (up to 3 octal digits); always a byte unless > 255 in UTF-8 or 16-bit mode \xhh hexadecimal byte (up to 2 hex digits) \x{hh...} hexadecimal character (any number of hex digits) \A pass the PCRE_ANCHORED option to pcre[16]_exec() or pcre[16]_dfa_exec() \B pass the PCRE_NOTBOL option to pcre[16]_exec() or pcre[16]_dfa_exec() \Cdd call pcre[16]_copy_substring() for substring dd after a successful match (number less than 32) \Cname call pcre[16]_copy_named_substring() for substring "name" after a successful match (name termin- ated by next non alphanumeric character) \C+ show the current captured substrings at callout time \C- do not supply a callout function \C!n return 1 instead of 0 when callout number n is reached \C!n!m return 1 instead of 0 when callout number n is reached for the nth time \C*n pass the number n (may be negative) as callout data; this is used as the callout return value \D use the pcre[16]_dfa_exec() match function \F only shortest match for pcre[16]_dfa_exec() \Gdd call pcre[16]_get_substring() for substring dd after a successful match (number less than 32) \Gname call pcre[16]_get_named_substring() for substring "name" after a successful match (name termin- ated by next non-alphanumeric character) \Jdd set up a JIT stack of dd kilobytes maximum (any number of digits) \L call pcre[16]_get_substringlist() after a successful match \M discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings \N pass the PCRE_NOTEMPTY option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the PCRE_NOTEMPTY_ATSTART option \Odd set the size of the output vector passed to pcre[16]_exec() to dd (any number of digits) \P pass the PCRE_PARTIAL_SOFT option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the PCRE_PARTIAL_HARD option \Qdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd (any number of digits) \R pass the PCRE_DFA_RESTART option to pcre[16]_dfa_exec() \S output details of memory get/free calls during matching \Y pass the PCRE_NO_START_OPTIMIZE option to pcre[16]_exec() or pcre[16]_dfa_exec() \Z pass the PCRE_NOTEOL option to pcre[16]_exec() or pcre[16]_dfa_exec() \? pass the PCRE_NO_UTF[8|16]_CHECK option to pcre[16]_exec() or pcre[16]_dfa_exec() \>dd start the match at offset dd (optional "-"; then any number of digits); this sets the startoffset argument for pcre[16]_exec() or pcre[16]_dfa_exec() \ pass the PCRE_NEWLINE_CR option to pcre[16]_exec() or pcre[16]_dfa_exec() \ pass the PCRE_NEWLINE_LF option to pcre[16]_exec() or pcre[16]_dfa_exec() \ pass the PCRE_NEWLINE_CRLF option to pcre[16]_exec() or pcre[16]_dfa_exec() \ pass the PCRE_NEWLINE_ANYCRLF option to pcre[16]_exec() or pcre[16]_dfa_exec() \ pass the PCRE_NEWLINE_ANY option to pcre[16]_exec() or pcre[16]_dfa_exec() The use of \x{hh...} is not dependent on the use of the /8 modifier on the pattern. It is recognized always. There may be any number of hexa- decimal digits inside the braces; invalid values provoke error mes- sages. Note that \xhh specifies one byte rather than one character in UTF-8 mode; this makes it possible to construct invalid UTF-8 sequences for testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8 character in UTF-8 mode, generating more than one byte if the value is greater than 127. When testing the 8-bit library not in UTF-8 mode, \x{hh} generates one byte for values less than 256, and causes an error for greater values. In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it possible to construct invalid UTF-16 sequences for testing purposes. The escapes that specify line ending sequences are literal strings, exactly as shown. No more than one newline setting should be present in any data line. A backslash followed by anything else just escapes the anything else. If the very last character is a backslash, it is ignored. This gives a way of passing an empty line as data, since a real empty line termi- nates the data input. The \J escape provides a way of setting the maximum stack size that is used by the just-in-time optimization code. It is ignored if JIT opti- mization is not being used. Providing a stack that is larger than the default 32K is necessary only for very complicated patterns. If \M is present, pcretest calls pcre[16]_exec() several times, with different values in the match_limit and match_limit_recursion fields of the pcre[16]_extra data structure, until it finds the minimum numbers for each parameter that allow pcre[16]_exec() to complete without error. Because this is testing a specific feature of the normal inter- pretive pcre[16]_exec() execution, the use of any JIT optimization that might have been set up by the /S+ qualifier of -s+ option is disabled. The match_limit number is a measure of the amount of backtracking that takes place, and checking it out can be instructive. For most simple matches, the number is quite small, but for patterns with very large numbers of matching possibilities, it can become large very quickly with increasing length of subject string. The match_limit_recursion number is a measure of how much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is needed to complete the match attempt. When \O is used, the value specified may be higher or lower than the size set by the -O command line option (or defaulted to 45); \O applies only to the call of pcre[16]_exec() for the line in which it appears. If the /P modifier was present on the pattern, causing the POSIX wrap- per API to be used, the only option-setting sequences that have any effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to regexec(). THE ALTERNATIVE MATCHING FUNCTION By default, pcretest uses the standard PCRE matching function, pcre[16]_exec() to match each data line. PCRE also supports an alterna- tive matching function, pcre[16]_dfa_test(), which operates in a dif- ferent way, and has some restrictions. The differences between the two functions are described in the pcrematching documentation. If a data line contains the \D escape sequence, or if the command line contains the -dfa option, the alternative matching function is used. This function finds all possible matches at a given point. If, however, the \F escape sequence is present in the data line, it stops after the first match is found. This is always the shortest possible match. DEFAULT OUTPUT FROM PCRETEST This section describes the output when the normal matching function, pcre[16]_exec(), is being used. When a match succeeds, pcretest outputs the list of captured substrings that pcre[16]_exec() returns, starting with number 0 for the string that matched the whole pattern. Otherwise, it outputs "No match" when the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the partially matching substring when pcre[16]_exec() returns PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was inspected during the partial match; it may include characters before the actual match start if a lookbehind assertion, \K, \b, or \B was involved.) For any other return, pcretest outputs the PCRE negative error number and a short descriptive phrase. If the error is a failed UTF string check, the offset of the start of the failing character and the reason code are also output, provided that the size of the output vector is at least two. Here is an example of an interactive pcretest run. $ pcretest PCRE version 8.13 2011-04-30 re> /^abc(\d+)/ data> abc123 0: abc123 1: 123 data> xyz No match Unset capturing substrings that are not followed by one that is set are not returned by pcre[16]_exec(), and are not shown by pcretest. In the following example, there are two capturing substrings, but when the first data line is matched, the second, unset substring is not shown. An "internal" unset substring is shown as "", as for the second data line. re> /(a)|(b)/ data> a 0: a 1: a data> b 0: b 1: 2: b If the strings contain any non-printing characters, they are output as \xhh escapes if the value is less than 256 and UTF mode is not set. Otherwise they are output as \x{hh...} escapes. See below for the defi- nition of non-printing characters. If the pattern has the /+ modifier, the output for substring 0 is followed by the the rest of the subject string, identified by "0+" like this: re> /cat/+ data> cataract 0: cat 0+ aract If the pattern has the /g or /G modifier, the results of successive matching attempts are output in sequence, like this: re> /\Bi(\w\w)/g data> Mississippi 0: iss 1: ss 0: iss 1: ss 0: ipp 1: pp "No match" is output only if the first match attempt fails. Here is an example of a failure message (the offset 4 that is specified by \>4 is past the end of the subject string): re> /xyz/ data> xyz\>4 Error -24 (bad offset value) If any of the sequences \C, \G, or \L are present in a data line that is successfully matched, the substrings extracted by the convenience functions are output with C, G, or L after the string number instead of a colon. This is in addition to the normal full list. The string length (that is, the return from the extraction function) is given in paren- theses after each string for \C and \G. Note that whereas patterns can be continued over several lines (a plain ">" prompt is used for continuations), data lines may not. However new- lines can be included in data by means of the \n escape (or \r, \r\n, etc., depending on the newline sequence setting). OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION When the alternative matching function, pcre[16]_dfa_exec(), is used (by means of the \D escape sequence or the -dfa command line option), the output consists of a list of all the matches that start at the first point in the subject where there is at least one match. For exam- ple: re> /(tang|tangerine|tan)/ data> yellow tangerine\D 0: tangerine 1: tang 2: tan (Using the normal matching function on this data finds only "tang".) The longest matching string is always given first (and numbered zero). After a PCRE_ERROR_PARTIAL return, the output is "Partial match:", fol- lowed by the partially matching substring. (Note that this is the entire substring that was inspected during the partial match; it may include characters before the actual match start if a lookbehind asser- tion, \K, \b, or \B was involved.) If /g is present on the pattern, the search for further matches resumes at the end of the longest match. For example: re> /(tang|tangerine|tan)/g data> yellow tangerine and tangy sultana\D 0: tangerine 1: tang 2: tan 0: tang 1: tan 0: tan Since the matching function does not support substring capture, the escape sequences that are concerned with captured substrings are not relevant. RESTARTING AFTER A PARTIAL MATCH When the alternative matching function has given the PCRE_ERROR_PARTIAL return, indicating that the subject partially matched the pattern, you can restart the match with additional subject data by means of the \R escape sequence. For example: re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ data> 23ja\P\D Partial match: 23ja data> n05\R\D 0: n05 For further information about partial matching, see the pcrepartial documentation. CALLOUTS If the pattern contains any callout requests, pcretest's callout func- tion is called during matching. This works with both matching func- tions. By default, the called function displays the callout number, the start and current positions in the text at the callout time, and the next pattern item to be tested. For example: --->pqrabcdef 0 ^ ^ \d This output indicates that callout number 0 occurred for a match attempt starting at the fourth character of the subject string, when the pointer was at the seventh character of the data, and when the next pattern item was \d. Just one circumflex is output if the start and current positions are the same. Callouts numbered 255 are assumed to be automatic callouts, inserted as a result of the /C pattern modifier. In this case, instead of showing the callout number, the offset in the pattern, preceded by a plus, is output. For example: re> /\d?[A-E]\*/C data> E* --->E* +0 ^ \d? +3 ^ [A-E] +8 ^^ \* +10 ^ ^ 0: E* If a pattern contains (*MARK) items, an additional line is output when- ever a change of latest mark is passed to the callout function. For example: re> /a(*MARK:X)bc/C data> abc --->abc +0 ^ a +1 ^^ (*MARK:X) +10 ^^ b Latest Mark: X +11 ^ ^ c +12 ^ ^ 0: abc The mark changes between matching "a" and "b", but stays the same for the rest of the match, so nothing more is output. If, as a result of backtracking, the mark reverts to being unset, the text "" is output. The callout function in pcretest returns zero (carry on matching) by default, but you can use a \C item in a data line (as described above) to change this and other parameters of the callout. Inserting callouts can be helpful when using pcretest to check compli- cated regular expressions. For further information about callouts, see the pcrecallout documentation. NON-PRINTING CHARACTERS When pcretest is outputting text in the compiled version of a pattern, bytes other than 32-126 are always treated as non-printing characters are are therefore shown as hex escapes. When pcretest is outputting text that is a matched part of a subject string, it behaves in the same way, unless a different locale has been set for the pattern (using the /L modifier). In this case, the isprint() function to distinguish printing and non-printing characters. SAVING AND RELOADING COMPILED PATTERNS The facilities described in this section are not available when the POSIX interface to PCRE is being used, that is, when the /P pattern modifier is specified. When the POSIX interface is not in use, you can cause pcretest to write a compiled pattern to a file, by following the modifiers with > and a file name. For example: /pattern/im >/some/file See the pcreprecompile documentation for a discussion about saving and re-using compiled patterns. Note that if the pattern was successfully studied with JIT optimization, the JIT data cannot be saved. The data that is written is binary. The first eight bytes are the length of the compiled pattern data followed by the length of the optional study data, each written as four bytes in big-endian order (most significant byte first). If there is no study data (either the pattern was not studied, or studying did not return any data), the sec- ond length is zero. The lengths are followed by an exact copy of the compiled pattern. If there is additional study data, this (excluding any JIT data) follows immediately after the compiled pattern. After writing the file, pcretest expects to read a new pattern. A saved pattern can be reloaded into pcretest by specifying < and a file name instead of a pattern. The name of the file must not contain a < character, as otherwise pcretest will interpret the line as a pattern delimited by < characters. For example: re> \fP. When there is more than one pattern (specified by the use of \fB-e\fP and/or \fB-f\fP), each pattern is applied to each line in the order in which they are defined, except that all the \fB-e\fP patterns are tried before the \fB-f\fP patterns. .P By default, as soon as one pattern matches (or fails to match when \fB-v\fP is used), no further patterns are considered. However, if \fB--colour\fP (or \fB--color\fP) is used to colour the matching substrings, or if \fB--only-matching\fP, \fB--file-offsets\fP, or \fB--line-offsets\fP is used to output only the part of the line that matched (either shown literally, or as an offset), scanning resumes immediately following the match, so that further matches on the same line can be found. If there are multiple patterns, they are all tried on the remainder of the line, but patterns that follow the one that matched are not tried on the earlier part of the line. .P This is the same behaviour as GNU grep, but it does mean that the order in which multiple patterns are specified can affect the output when one of the above options is used. .P Patterns that can match an empty string are accepted, but empty string matches are never recognized. An example is the pattern "(super)?(man)?", in which all components are optional. This pattern finds all occurrences of both "super" and "man"; the output differs from matching with "super|man" when only the matching substrings are being shown. .P If the \fBLC_ALL\fP or \fBLC_CTYPE\fP environment variable is set, \fBpcregrep\fP uses the value to set a locale when calling the PCRE library. The \fB--locale\fP option can be used to override this. . . .SH "SUPPORT FOR COMPRESSED FILES" .rs .sp It is possible to compile \fBpcregrep\fP so that it uses \fBlibz\fP or \fBlibbz2\fP to read files whose names end in \fB.gz\fP or \fB.bz2\fP, respectively. You can find out whether your binary has support for one or both of these file types by running it with the \fB--help\fP option. If the appropriate support is not present, files are treated as plain text. The standard input is always so treated. . . .SH "BINARY FILES" .rs .sp By default, a file that contains a binary zero byte within the first 1024 bytes is identified as a binary file, and is processed specially. (GNU grep also identifies binary files in this manner.) See the \fB--binary-files\fP option for a means of changing the way binary files are handled. . . .SH OPTIONS .rs .sp The order in which some of the options appear can affect the output. For example, both the \fB-h\fP and \fB-l\fP options affect the printing of file names. Whichever comes later in the command line will be the one that takes effect. Numerical values for options may be followed by K or M, to signify multiplication by 1024 or 1024*1024 respectively. .TP 10 \fB--\fP This terminates the list of options. It is useful if the next item on the command line starts with a hyphen but is not an option. This allows for the processing of patterns and filenames that start with hyphens. .TP \fB-A\fP \fInumber\fP, \fB--after-context=\fP\fInumber\fP Output \fInumber\fP lines of context after each matching line. If filenames and/or line numbers are being output, a hyphen separator is used instead of a colon for the context lines. A line containing "--" is output between each group of lines, unless they are in fact contiguous in the input file. The value of \fInumber\fP is expected to be relatively small. However, \fBpcregrep\fP guarantees to have up to 8K of following text available for context output. .TP \fB-a\fP, \fB--text\fP Treat binary files as text. This is equivalent to \fB--binary-files\fP=\fItext\fP. .TP \fB-B\fP \fInumber\fP, \fB--before-context=\fP\fInumber\fP Output \fInumber\fP lines of context before each matching line. If filenames and/or line numbers are being output, a hyphen separator is used instead of a colon for the context lines. A line containing "--" is output between each group of lines, unless they are in fact contiguous in the input file. The value of \fInumber\fP is expected to be relatively small. However, \fBpcregrep\fP guarantees to have up to 8K of preceding text available for context output. .TP \fB--binary-files=\fP\fIword\fP Specify how binary files are to be processed. If the word is "binary" (the default), pattern matching is performed on binary files, but the only output is "Binary file matches" when a match succeeds. If the word is "text", which is equivalent to the \fB-a\fP or \fB--text\fP option, binary files are processed in the same way as any other file. In this case, when a match succeeds, the output may be binary garbage, which can have nasty effects if sent to a terminal. If the word is "without-match", which is equivalent to the \fB-I\fP option, binary files are not processed at all; they are assumed not to be of interest. .TP \fB--buffer-size=\fP\fInumber\fP Set the parameter that controls how much memory is used for buffering files that are being scanned. .TP \fB-C\fP \fInumber\fP, \fB--context=\fP\fInumber\fP Output \fInumber\fP lines of context both before and after each matching line. This is equivalent to setting both \fB-A\fP and \fB-B\fP to the same value. .TP \fB-c\fP, \fB--count\fP Do not output individual lines from the files that are being scanned; instead output the number of lines that would otherwise have been shown. If no lines are selected, the number zero is output. If several files are are being scanned, a count is output for each of them. However, if the \fB--files-with-matches\fP option is also used, only those files whose counts are greater than zero are listed. When \fB-c\fP is used, the \fB-A\fP, \fB-B\fP, and \fB-C\fP options are ignored. .TP \fB--colour\fP, \fB--color\fP If this option is given without any data, it is equivalent to "--colour=auto". If data is required, it must be given in the same shell item, separated by an equals sign. .TP \fB--colour=\fP\fIvalue\fP, \fB--color=\fP\fIvalue\fP This option specifies under what circumstances the parts of a line that matched a pattern should be coloured in the output. By default, the output is not coloured. The value (which is optional, see above) may be "never", "always", or "auto". In the latter case, colouring happens only if the standard output is connected to a terminal. More resources are used when colouring is enabled, because \fBpcregrep\fP has to search for all possible matches in a line, not just one, in order to colour them all. .sp The colour that is used can be specified by setting the environment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value of this variable should be a string of two numbers, separated by a semicolon. They are copied directly into the control string for setting colour on a terminal, so it is your responsibility to ensure that they make sense. If neither of the environment variables is set, the default is "1;31", which gives red. .TP \fB-D\fP \fIaction\fP, \fB--devices=\fP\fIaction\fP If an input path is not a regular file or a directory, "action" specifies how it is to be processed. Valid values are "read" (the default) or "skip" (silently skip the path). .TP \fB-d\fP \fIaction\fP, \fB--directories=\fP\fIaction\fP If an input path is a directory, "action" specifies how it is to be processed. Valid values are "read" (the default), "recurse" (equivalent to the \fB-r\fP option), or "skip" (silently skip the path). In the default case, directories are read as if they were ordinary files. In some operating systems the effect of reading a directory like this is an immediate end-of-file. .TP \fB-e\fP \fIpattern\fP, \fB--regex=\fP\fIpattern\fP, \fB--regexp=\fP\fIpattern\fP Specify a pattern to be matched. This option can be used multiple times in order to specify several patterns. It can also be used as a way of specifying a single pattern that starts with a hyphen. When \fB-e\fP is used, no argument pattern is taken from the command line; all arguments are treated as file names. There is an overall maximum of 100 patterns. They are applied to each line in the order in which they are defined until one matches (or fails to match if \fB-v\fP is used). If \fB-f\fP is used with \fB-e\fP, the command line patterns are matched first, followed by the patterns from the file, independent of the order in which these options are specified. Note that multiple use of \fB-e\fP is not the same as a single pattern with alternatives. For example, X|Y finds the first character in a line that is X or Y, whereas if the two patterns are given separately, \fBpcregrep\fP finds X if it is present, even if it follows Y in the line. It finds Y only if there is no X in the line. This really matters only if you are using \fB-o\fP to show the part(s) of the line that matched. .TP \fB--exclude\fP=\fIpattern\fP When \fBpcregrep\fP is searching the files in a directory as a consequence of the \fB-r\fP (recursive search) option, any regular files whose names match the pattern are excluded. Subdirectories are not excluded by this option; they are searched recursively, subject to the \fB--exclude-dir\fP and \fB--include_dir\fP options. The pattern is a PCRE regular expression, and is matched against the final component of the file name (not the entire path). If a file name matches both \fB--include\fP and \fB--exclude\fP, it is excluded. There is no short form for this option. .TP \fB--exclude-dir\fP=\fIpattern\fP When \fBpcregrep\fP is searching the contents of a directory as a consequence of the \fB-r\fP (recursive search) option, any subdirectories whose names match the pattern are excluded. (Note that the \fP--exclude\fP option does not affect subdirectories.) The pattern is a PCRE regular expression, and is matched against the final component of the name (not the entire path). If a subdirectory name matches both \fB--include-dir\fP and \fB--exclude-dir\fP, it is excluded. There is no short form for this option. .TP \fB-F\fP, \fB--fixed-strings\fP Interpret each pattern as a list of fixed strings, separated by newlines, instead of as a regular expression. The \fB-w\fP (match as a word) and \fB-x\fP (match whole line) options can be used with \fB-F\fP. They apply to each of the fixed strings. A line is selected if any of the fixed strings are found in it (subject to \fB-w\fP or \fB-x\fP, if present). .TP \fB-f\fP \fIfilename\fP, \fB--file=\fP\fIfilename\fP Read a number of patterns from the file, one per line, and match them against each line of input. A data line is output if any of the patterns match it. The filename can be given as "-" to refer to the standard input. When \fB-f\fP is used, patterns specified on the command line using \fB-e\fP may also be present; they are tested before the file's patterns. However, no other pattern is taken from the command line; all arguments are treated as the names of paths to be searched. There is an overall maximum of 100 patterns. Trailing white space is removed from each line, and blank lines are ignored. An empty file contains no patterns and therefore matches nothing. See also the comments about multiple patterns versus a single pattern with alternatives in the description of \fB-e\fP above. .TP \fB--file-list\fP=\fIfilename\fP Read a list of files to be searched from the given file, one per line. Trailing white space is removed from each line, and blank lines are ignored. These files are searched before any others that may be listed on the command line. The filename can be given as "-" to refer to the standard input. If \fB--file\fP and \fB--file-list\fP are both specified as "-", patterns are read first. This is useful only when the standard input is a terminal, from which further lines (the list of files) can be read after an end-of-file indication. .TP \fB--file-offsets\fP Instead of showing lines or parts of lines that match, show each match as an offset from the start of the file and a length, separated by a comma. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and \fB-C\fP options are ignored. If there is more than one match in a line, each of them is shown separately. This option is mutually exclusive with \fB--line-offsets\fP and \fB--only-matching\fP. .TP \fB-H\fP, \fB--with-filename\fP Force the inclusion of the filename at the start of output lines when searching a single file. By default, the filename is not shown in this case. For matching lines, the filename is followed by a colon; for context lines, a hyphen separator is used. If a line number is also being output, it follows the file name. .TP \fB-h\fP, \fB--no-filename\fP Suppress the output filenames when searching multiple files. By default, filenames are shown when multiple files are searched. For matching lines, the filename is followed by a colon; for context lines, a hyphen separator is used. If a line number is also being output, it follows the file name. .TP \fB--help\fP Output a help message, giving brief details of the command options and file type support, and then exit. .TP \fB-I\fP Treat binary files as never matching. This is equivalent to \fB--binary-files\fP=\fIwithout-match\fP. .TP \fB-i\fP, \fB--ignore-case\fP Ignore upper/lower case distinctions during comparisons. .TP \fB--include\fP=\fIpattern\fP When \fBpcregrep\fP is searching the files in a directory as a consequence of the \fB-r\fP (recursive search) option, only those regular files whose names match the pattern are included. Subdirectories are always included and searched recursively, subject to the \fP--include-dir\fP and \fB--exclude-dir\fP options. The pattern is a PCRE regular expression, and is matched against the final component of the file name (not the entire path). If a file name matches both \fB--include\fP and \fB--exclude\fP, it is excluded. There is no short form for this option. .TP \fB--include-dir\fP=\fIpattern\fP When \fBpcregrep\fP is searching the contents of a directory as a consequence of the \fB-r\fP (recursive search) option, only those subdirectories whose names match the pattern are included. (Note that the \fB--include\fP option does not affect subdirectories.) The pattern is a PCRE regular expression, and is matched against the final component of the name (not the entire path). If a subdirectory name matches both \fB--include-dir\fP and \fB--exclude-dir\fP, it is excluded. There is no short form for this option. .TP \fB-L\fP, \fB--files-without-match\fP Instead of outputting lines from the files, just output the names of the files that do not contain any lines that would have been output. Each file name is output once, on a separate line. .TP \fB-l\fP, \fB--files-with-matches\fP Instead of outputting lines from the files, just output the names of the files containing lines that would have been output. Each file name is output once, on a separate line. Searching normally stops as soon as a matching line is found in a file. However, if the \fB-c\fP (count) option is also used, matching continues in order to obtain the correct count, and those files that have at least one match are listed along with their counts. Using this option with \fB-c\fP is a way of suppressing the listing of files with no matches. .TP \fB--label\fP=\fIname\fP This option supplies a name to be used for the standard input when file names are being output. If not supplied, "(standard input)" is used. There is no short form for this option. .TP \fB--line-buffered\fP When this option is given, input is read and processed line by line, and the output is flushed after each write. By default, input is read in large chunks, unless \fBpcregrep\fP can determine that it is reading from a terminal (which is currently possible only in Unix environments). Output to terminal is normally automatically flushed by the operating system. This option can be useful when the input or output is attached to a pipe and you do not want \fBpcregrep\fP to buffer up large amounts of data. However, its use will affect performance, and the \fB-M\fP (multiline) option ceases to work. .TP \fB--line-offsets\fP Instead of showing lines or parts of lines that match, show each match as a line number, the offset from the start of the line, and a length. The line number is terminated by a colon (as usual; see the \fB-n\fP option), and the offset and length are separated by a comma. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and \fB-C\fP options are ignored. If there is more than one match in a line, each of them is shown separately. This option is mutually exclusive with \fB--file-offsets\fP and \fB--only-matching\fP. .TP \fB--locale\fP=\fIlocale-name\fP This option specifies a locale to be used for pattern matching. It overrides the value in the \fBLC_ALL\fP or \fBLC_CTYPE\fP environment variables. If no locale is specified, the PCRE library's default (usually the "C" locale) is used. There is no short form for this option. .TP \fB--match-limit\fP=\fInumber\fP Processing some regular expression patterns can require a very large amount of memory, leading in some cases to a program crash if not enough is available. Other patterns may take a very long time to search for all possible matching strings. The \fBpcre_exec()\fP function that is called by \fBpcregrep\fP to do the matching has two parameters that can limit the resources that it uses. .sp The \fB--match-limit\fP option provides a means of limiting resource usage when processing patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats. Internally, PCRE uses a function called \fBmatch()\fP which it calls repeatedly (sometimes recursively). The limit set by \fB--match-limit\fP is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. .sp The \fB--recursion-limit\fP option is similar to \fB--match-limit\fP, but instead of limiting the total number of times that \fBmatch()\fP is called, it limits the depth of recursive calls, which in turn limits the amount of memory that can be used. The recursion depth is a smaller number than the total number of calls, because not all calls to \fBmatch()\fP are recursive. This limit is of use only if it is set smaller than \fB--match-limit\fP. .sp There are no short forms for these options. The default settings are specified when the PCRE library is compiled, with the default default being 10 million. .TP \fB-M\fP, \fB--multiline\fP Allow patterns to match more than one line. When this option is given, patterns may usefully contain literal newline characters and internal occurrences of ^ and $ characters. The output for a successful match may consist of more than one line, the last of which is the one in which the match ended. If the matched string ends with a newline sequence the output ends at the end of that line. .sp When this option is set, the PCRE library is called in "multiline" mode. There is a limit to the number of lines that can be matched, imposed by the way that \fBpcregrep\fP buffers the input file as it scans it. However, \fBpcregrep\fP ensures that at least 8K characters or the rest of the document (whichever is the shorter) are available for forward matching, and similarly the previous 8K characters (or all the previous characters, if fewer than 8K) are guaranteed to be available for lookbehind assertions. This option does not work when input is read line by line (see \fP--line-buffered\fP.) .TP \fB-N\fP \fInewline-type\fP, \fB--newline\fP=\fInewline-type\fP The PCRE library supports five different conventions for indicating the ends of lines. They are the single-character sequences CR (carriage return) and LF (linefeed), the two-character sequence CRLF, an "anycrlf" convention, which recognizes any of the preceding three types, and an "any" convention, in which any Unicode line ending sequence is assumed to end a line. The Unicode sequences are the three just mentioned, plus VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). .sp When the PCRE library is built, a default line-ending sequence is specified. This is normally the standard sequence for the operating system. Unless otherwise specified by this option, \fBpcregrep\fP uses the library's default. The possible values for this option are CR, LF, CRLF, ANYCRLF, or ANY. This makes it possible to use \fBpcregrep\fP on files that have come from other environments without having to modify their line endings. If the data that is being scanned does not agree with the convention set by this option, \fBpcregrep\fP may behave in strange ways. .TP \fB-n\fP, \fB--line-number\fP Precede each output line by its line number in the file, followed by a colon for matching lines or a hyphen for context lines. If the filename is also being output, it precedes the line number. This option is forced if \fB--line-offsets\fP is used. .TP \fB--no-jit\fP If the PCRE library is built with support for just-in-time compiling (which speeds up matching), \fBpcregrep\fP automatically makes use of this, unless it was explicitly disabled at build time. This option can be used to disable the use of JIT at run time. It is provided for testing and working round problems. It should never be needed in normal use. .TP \fB-o\fP, \fB--only-matching\fP Show only the part of the line that matched a pattern instead of the whole line. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and \fB-C\fP options are ignored. If there is more than one match in a line, each of them is shown separately. If \fB-o\fP is combined with \fB-v\fP (invert the sense of the match to find non-matching lines), no output is generated, but the return code is set appropriately. If the matched portion of the line is empty, nothing is output unless the file name or line number are being printed, in which case they are shown on an otherwise empty line. This option is mutually exclusive with \fB--file-offsets\fP and \fB--line-offsets\fP. .TP \fB-o\fP\fInumber\fP, \fB--only-matching\fP=\fInumber\fP Show only the part of the line that matched the capturing parentheses of the given number. Up to 32 capturing parentheses are supported. Because these options can be given without an argument (see above), if an argument is present, it must be given in the same shell item, for example, -o3 or --only-matching=2. The comments given for the non-argument case above also apply to this case. If the specified capturing parentheses do not exist in the pattern, or were not set in the match, nothing is output unless the file name or line number are being printed. .TP \fB-q\fP, \fB--quiet\fP Work quietly, that is, display nothing except error messages. The exit status indicates whether or not any matches were found. .TP \fB-r\fP, \fB--recursive\fP If any given path is a directory, recursively scan the files it contains, taking note of any \fB--include\fP and \fB--exclude\fP settings. By default, a directory is read as a normal file; in some operating systems this gives an immediate end-of-file. This option is a shorthand for setting the \fB-d\fP option to "recurse". .TP \fB--recursion-limit\fP=\fInumber\fP See \fB--match-limit\fP above. .TP \fB-s\fP, \fB--no-messages\fP Suppress error messages about non-existent or unreadable files. Such files are quietly skipped. However, the return code is still 2, even if matches were found in other files. .TP \fB-u\fP, \fB--utf-8\fP Operate in UTF-8 mode. This option is available only if PCRE has been compiled with UTF-8 support. Both patterns and subject lines must be valid strings of UTF-8 characters. .TP \fB-V\fP, \fB--version\fP Write the version numbers of \fBpcregrep\fP and the PCRE library that is being used to the standard error stream. .TP \fB-v\fP, \fB--invert-match\fP Invert the sense of the match, so that lines which do \fInot\fP match any of the patterns are the ones that are found. .TP \fB-w\fP, \fB--word-regex\fP, \fB--word-regexp\fP Force the patterns to match only whole words. This is equivalent to having \eb at the start and end of the pattern. .TP \fB-x\fP, \fB--line-regex\fP, \fB--line-regexp\fP Force the patterns to be anchored (each must start matching at the beginning of a line) and in addition, require them to match entire lines. This is equivalent to having ^ and $ characters at the start and end of each alternative branch in every pattern. . . .SH "ENVIRONMENT VARIABLES" .rs .sp The environment variables \fBLC_ALL\fP and \fBLC_CTYPE\fP are examined, in that order, for a locale. The first one that is set is used. This can be overridden by the \fB--locale\fP option. If no locale is set, the PCRE library's default (usually the "C" locale) is used. . . .SH "NEWLINES" .rs .sp The \fB-N\fP (\fB--newline\fP) option allows \fBpcregrep\fP to scan files with different newline conventions from the default. However, the setting of this option does not affect the way in which \fBpcregrep\fP writes information to the standard error and output streams. It uses the string "\en" in C \fBprintf()\fP calls to indicate newlines, relying on the C I/O library to convert this to an appropriate sequence if the output is sent to a file. . . .SH "OPTIONS COMPATIBILITY" .rs .sp Many of the short and long forms of \fBpcregrep\fP's options are the same as in the GNU \fBgrep\fP program. Any long option of the form \fB--xxx-regexp\fP (GNU terminology) is also available as \fB--xxx-regex\fP (PCRE terminology). However, the \fB--file-list\fP, \fB--file-offsets\fP, \fB--include-dir\fP, \fB--line-offsets\fP, \fB--locale\fP, \fB--match-limit\fP, \fB-M\fP, \fB--multiline\fP, \fB-N\fP, \fB--newline\fP, \fB--recursion-limit\fP, \fB-u\fP, and \fB--utf-8\fP options are specific to \fBpcregrep\fP, as is the use of the \fB--only-matching\fP option with a capturing parentheses number. .P Although most of the common options work the same way, a few are different in \fBpcregrep\fP. For example, the \fB--include\fP option's argument is a glob for GNU \fBgrep\fP, but a regular expression for \fBpcregrep\fP. If both the \fB-c\fP and \fB-l\fP options are given, GNU grep lists only file names, without counts, but \fBpcregrep\fP gives the counts. . . .SH "OPTIONS WITH DATA" .rs .sp There are four different ways in which an option with data can be specified. If a short form option is used, the data may follow immediately, or (with one exception) in the next command line item. For example: .sp -f/some/file -f /some/file .sp The exception is the \fB-o\fP option, which may appear with or without data. Because of this, if data is present, it must follow immediately in the same item, for example -o3. .P If a long form option is used, the data may appear in the same command line item, separated by an equals character, or (with two exceptions) it may appear in the next command line item. For example: .sp --file=/some/file --file /some/file .sp Note, however, that if you want to supply a file name beginning with ~ as data in a shell command, and have the shell expand ~ to a home directory, you must separate the file name from the option, because the shell does not treat ~ specially unless it is at the start of an item. .P The exceptions to the above are the \fB--colour\fP (or \fB--color\fP) and \fB--only-matching\fP options, for which the data is optional. If one of these options does have data, it must be given in the first form, using an equals character. Otherwise \fBpcregrep\fP will assume that it has no data. . . .SH "MATCHING ERRORS" .rs .sp It is possible to supply a regular expression that takes a very long time to fail to match certain lines. Such patterns normally involve nested indefinite repeats, for example: (a+)*\ed when matched against a line of a's with no final digit. The PCRE matching function has a resource limit that causes it to abort in these circumstances. If this happens, \fBpcregrep\fP outputs an error message and the line that caused the problem to the standard error stream. If there are more than 20 such errors, \fBpcregrep\fP gives up. .P The \fB--match-limit\fP option of \fBpcregrep\fP can be used to set the overall resource limit; there is a second option called \fB--recursion-limit\fP that sets a limit on the amount of memory (usually stack) that is used (see the discussion of these options above). . . .SH DIAGNOSTICS .rs .sp Exit status is 0 if any matches were found, 1 if no matches were found, and 2 for syntax errors, overlong lines, non-existent or inaccessible files (even if matches were found in other files) or too many matching errors. Using the \fB-s\fP option to suppress error messages about inaccessible files does not affect the return code. . . .SH "SEE ALSO" .rs .sp \fBpcrepattern\fP(3), \fBpcretest\fP(1). . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 04 March 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_free_study.30000644000222100022210000000120411735631300013312 00000000000000.TH PCRE_FREE_STUDY 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B void pcre_free_study(pcre_extra *\fIextra\fP); .PP .B void pcre16_free_study(pcre16_extra *\fIextra\fP); . .SH DESCRIPTION .rs .sp This function is used to free the memory used for the data generated by a call to \fBpcre[16]_study()\fP when it is no longer needed. The argument must be the result of such a call. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_jit_stack_alloc.30000644000222100022210000000204311760163326014276 00000000000000.TH PCRE_JIT_STACK_ALLOC 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP, .ti +5n .B int \fImaxsize\fP); .PP .B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP, .ti +5n .B int \fImaxsize\fP); . .SH DESCRIPTION .rs .sp This function is used to create a stack for use by the code compiled by the JIT optimization of \fBpcre[16]_study()\fP. The arguments are a starting size for the stack, and a maximum size to which it is allowed to grow. The result can be passed to the JIT run-time code by \fBpcre[16]_assign_jit_stack()\fP, or that function can set up a callback for obtaining a stack. A maximum stack size of 512K to 1M should be more than enough for any pattern. For more details, see the .\" HREF \fBpcrejit\fP .\" page. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_dfa_exec.30000644000222100022210000001115711735631247012721 00000000000000.TH PCRE_DFA_EXEC 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, .ti +5n .B int *\fIworkspace\fP, int \fIwscount\fP); .PP .B int pcre16_dfa_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," .ti +5n .B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, .ti +5n .B int *\fIworkspace\fP, int \fIwscount\fP); . .SH DESCRIPTION .rs .sp This function matches a compiled regular expression against a given subject string, using an alternative matching algorithm that scans the subject string just once (\fInot\fP Perl-compatible). Note that the main, Perl-compatible, matching function is \fBpcre[16]_exec()\fP. The arguments for this function are: .sp \fIcode\fP Points to the compiled pattern \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure, or is NULL \fIsubject\fP Points to the subject string \fIlength\fP Length of the subject string, in bytes \fIstartoffset\fP Offset in bytes in the subject at which to start matching \fIoptions\fP Option bits \fIovector\fP Points to a vector of ints for result offsets \fIovecsize\fP Number of elements in the vector \fIworkspace\fP Points to a vector of ints used as working space \fIwscount\fP Number of elements in the vector .sp The options are: .sp PCRE_ANCHORED Match only at the first position PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF PCRE_BSR_UNICODE \eR matches all Unicode line endings PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, & CRLF as newline sequences PCRE_NEWLINE_CR Recognize CR as the only newline sequence PCRE_NEWLINE_CRLF Recognize CRLF as the only newline sequence PCRE_NEWLINE_LF Recognize LF as the only newline sequence PCRE_NOTBOL Subject is not the beginning of a line PCRE_NOTEOL Subject is not the end of a line PCRE_NOTEMPTY An empty string is not a valid match PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject is not a valid match PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16 validity (only relevant if PCRE_UTF16 was set at compile time) PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8 validity (only relevant if PCRE_UTF8 was set at compile time) PCRE_PARTIAL ) Return PCRE_ERROR_PARTIAL for a partial PCRE_PARTIAL_SOFT ) match if no full matches are found PCRE_PARTIAL_HARD Return PCRE_ERROR_PARTIAL for a partial match even if there is a full match as well PCRE_DFA_SHORTEST Return only the shortest match PCRE_DFA_RESTART Restart after a partial match .sp There are restrictions on what may appear in a pattern when using this matching function. Details are given in the .\" HREF \fBpcrematching\fP .\" documentation. For details of partial matching, see the .\" HREF \fBpcrepartial\fP .\" page. .P A \fBpcre[16]_extra\fP structure contains the following fields: .sp \fIflags\fP Bits indicating which fields are set \fIstudy_data\fP Opaque data from \fBpcre[16]_study()\fP \fImatch_limit\fP Limit on internal resource use \fImatch_limit_recursion\fP Limit on internal recursion depth \fIcallout_data\fP Opaque data passed back to callouts \fItables\fP Points to character tables or is NULL \fImark\fP For passing back a *MARK pointer \fIexecutable_jit\fP Opaque data from JIT compilation .sp The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. For this matching function, the \fImatch_limit\fP and \fImatch_limit_recursion\fP fields are not used, and must not be set. The PCRE_EXTRA_EXECUTABLE_JIT flag and the corresponding variable are ignored. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_free_substring_list.30000644000222100022210000000125111735631332015224 00000000000000.TH PCRE_FREE_SUBSTRING_LIST 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B void pcre_free_substring_list(const char **\fIstringptr\fP); .PP .B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for freeing the store obtained by a previous call to \fBpcre[16]_get_substring_list()\fP. Its only argument is a pointer to the list of string pointers. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_version.30000644000222100022210000000112711735631701012637 00000000000000.TH PCRE_VERSION 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B const char *pcre_version(void); .PP .B const char *pcre16_version(void); . .SH DESCRIPTION .rs .sp This function (even in the 16-bit library) returns a zero-terminated, 8-bit character string that gives the version number of the PCRE library and the date of its release. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_utf16_to_host_byte_order.30000644000222100022210000000272411735631665016111 00000000000000.TH PCRE_UTF16_TO_HOST_BYTE_ORDER 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *\fIoutput\fP, .ti +5n .B PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIhost_byte_order\fP, .ti +5n .B int \fIkeep_boms\fP); . . .SH DESCRIPTION .rs .sp This function, which exists only in the 16-bit library, converts a UTF-16 string to the correct order for the current host, taking account of any byte order marks (BOMs) within the string. Its arguments are: .sp \fIoutput\fP pointer to output buffer, may be the same as \fIinput\fP \fIinput\fP pointer to input buffer \fIlength\fP number of 16-bit units in the input, or negative for a zero-terminated string \fIhost_byte_order\fP a NULL value or a non-zero value pointed to means start in host byte order \fIkeep_boms\fP if non-zero, BOMs are copied to the output string .sp The result of the function is the number of 16-bit units placed into the output buffer, including the zero terminator if the string was zero-terminated. .P If \fIhost_byte_order\fP is not NULL, it is set to indicate the byte order that is current at the end of the string. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcrecompat.30000644000222100022210000002061711762200400012267 00000000000000.TH PCRECOMPAT 3 "08 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "DIFFERENCES BETWEEN PCRE AND PERL" .rs .sp This document describes the differences in the ways that PCRE and Perl handle regular expressions. The differences described here are with respect to Perl versions 5.10 and above. .P 1. PCRE has only a subset of Perl's Unicode support. Details of what it does have are given in the .\" HREF \fBpcreunicode\fP .\" page. .P 2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do not mean what you might think. For example, (?!a){3} does not assert that the next three characters are not "a". It just asserts that the next character is not "a" three times (in principle: PCRE optimizes this to run the assertion just once). Perl allows repeat quantifiers on other assertions such as \eb, but these do not seem to have any use. .P 3. Capturing subpatterns that occur inside negative lookahead assertions are counted, but their entries in the offsets vector are never set. Perl sets its numerical variables from any such patterns that are matched before the assertion fails to match something (thereby succeeding), but only if the negative lookahead assertion contains just one branch. .P 4. Though binary zero characters are supported in the subject string, they are not allowed in a pattern string because it is passed as a normal C string, terminated by zero. The escape sequence \e0 can be used in the pattern to represent a binary zero. .P 5. The following Perl escape sequences are not supported: \el, \eu, \eL, \eU, and \eN when followed by a character name or Unicode value. (\eN on its own, matching a non-newline character, is supported.) In fact these are implemented by Perl's general string-handling and are not part of its pattern matching engine. If any of these are encountered by PCRE, an error is generated by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, \eU and \eu are interpreted as JavaScript interprets them. .P 6. The Perl escape sequences \ep, \eP, and \eX are supported only if PCRE is built with Unicode character property support. The properties that can be tested with \ep and \eP are limited to the general category properties such as Lu and Nd, script names such as Greek or Han, and the derived properties Any and L&. PCRE does support the Cs (surrogate) property, which Perl does not; the Perl documentation says "Because Perl hides the need for the user to understand the internal representation of Unicode characters, there is no need to implement the somewhat messy concept of surrogates." .P 7. PCRE implements a simpler version of \eX than Perl, which changed to make \eX match what Unicode calls an "extended grapheme cluster". This is more complicated than an extended Unicode sequence, which is what PCRE matches. .P 8. PCRE does support the \eQ...\eE escape for quoting substrings. Characters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they cause variable interpolation (but of course PCRE does not have variables). Note the following examples: .sp Pattern PCRE matches Perl matches .sp .\" JOIN \eQabc$xyz\eE abc$xyz abc followed by the contents of $xyz \eQabc\e$xyz\eE abc\e$xyz abc\e$xyz \eQabc\eE\e$\eQxyz\eE abc$xyz abc$xyz .sp The \eQ...\eE sequence is recognized both inside and outside character classes. .P 9. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) constructions. However, there is support for recursive patterns. This is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout" feature allows an external function to be called during pattern matching. See the .\" HREF \fBpcrecallout\fP .\" documentation for details. .P 10. Subpatterns that are called as subroutines (whether or not recursively) are always treated as atomic groups in PCRE. This is like Python, but unlike Perl. Captured values that are set outside a subroutine call can be reference from inside in PCRE, but not in Perl. There is a discussion that explains these differences in more detail in the .\" HTML .\" section on recursion differences from Perl .\" in the .\" HREF \fBpcrepattern\fP .\" page. .P 11. If any of the backtracking control verbs are used in an assertion or in a subpattern that is called as a subroutine (whether or not recursively), their effect is confined to that subpattern; it does not extend to the surrounding pattern. This is not always the case in Perl. In particular, if (*THEN) is present in a group that is called as a subroutine, its action is limited to that group, even if the group does not contain any | characters. There is one exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a successful positive assertion \fIis\fP passed back when a match succeeds (compare capturing parentheses in assertions). Note that such subpatterns are processed as anchored at the point where they are tested. .P 12. There are some differences that are concerned with the settings of captured strings when part of a pattern is repeated. For example, matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b". .P 13. PCRE's handling of duplicate subpattern numbers and duplicate subpattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external table to translate between numbers and names. In particular, a pattern such as (?|(?A)|(?" to prompt for regular expressions, and "data>" to prompt for data lines. .P When \fBpcretest\fP is built, a configuration option can specify that it should be linked with the \fBlibreadline\fP library. When this is done, if the input is from a terminal, it is read using the \fBreadline()\fP function. This provides line-editing and history facilities. The output from the \fB-help\fP option states whether or not \fBreadline()\fP will be used. .P The program handles any number of sets of input on a single input file. Each set starts with a regular expression, and continues with any number of data lines to be matched against the pattern. .P Each data line is matched separately and independently. If you want to do multi-line matches, you have to use the \en escape sequence (or \er or \er\en, etc., depending on the newline setting) in a single line of input to encode the newline sequences. There is no limit on the length of data lines; the input buffer is automatically extended if it is too small. .P An empty line signals the end of the data lines, at which point a new regular expression is read. The regular expressions are given enclosed in any non-alphanumeric delimiters other than backslash, for example: .sp /(a|bc)x+yz/ .sp White space before the initial delimiter is ignored. A regular expression may be continued over several input lines, in which case the newline characters are included within it. It is possible to include the delimiter within the pattern by escaping it, for example .sp /abc\e/def/ .sp If you do so, the escape and the delimiter form part of the pattern, but since delimiters are always non-alphanumeric, this does not affect its interpretation. If the terminating delimiter is immediately followed by a backslash, for example, .sp /abc/\e .sp then a backslash is added to the end of the pattern. This is done to provide a way of testing the error condition that arises if a pattern finishes with a backslash, because .sp /abc\e/ .sp is interpreted as the first line of a pattern that starts with "abc/", causing pcretest to read the next line as a continuation of the regular expression. . . .SH "PATTERN MODIFIERS" .rs .sp A pattern may be followed by any number of modifiers, which are mostly single characters. Following Perl usage, these are referred to below as, for example, "the \fB/i\fP modifier", even though the delimiter of the pattern need not always be a slash, and no slash is used when writing modifiers. White space may appear between the final pattern delimiter and the first modifier, and between the modifiers themselves. .P The \fB/i\fP, \fB/m\fP, \fB/s\fP, and \fB/x\fP modifiers set the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when \fBpcre[16]_compile()\fP is called. These four modifier letters have the same effect as they do in Perl. For example: .sp /caseless/i .sp The following table shows additional modifiers for setting PCRE compile-time options that do not correspond to anything in Perl: .sp \fB/8\fP PCRE_UTF8 ) when using the 8-bit \fB/?\fP PCRE_NO_UTF8_CHECK ) library .sp \fB/8\fP PCRE_UTF16 ) when using the 16-bit \fB/?\fP PCRE_NO_UTF16_CHECK ) library .sp \fB/A\fP PCRE_ANCHORED \fB/C\fP PCRE_AUTO_CALLOUT \fB/E\fP PCRE_DOLLAR_ENDONLY \fB/f\fP PCRE_FIRSTLINE \fB/J\fP PCRE_DUPNAMES \fB/N\fP PCRE_NO_AUTO_CAPTURE \fB/U\fP PCRE_UNGREEDY \fB/W\fP PCRE_UCP \fB/X\fP PCRE_EXTRA \fB/Y\fP PCRE_NO_START_OPTIMIZE \fB/\fP PCRE_JAVASCRIPT_COMPAT \fB/\fP PCRE_NEWLINE_CR \fB/\fP PCRE_NEWLINE_LF \fB/\fP PCRE_NEWLINE_CRLF \fB/\fP PCRE_NEWLINE_ANYCRLF \fB/\fP PCRE_NEWLINE_ANY \fB/\fP PCRE_BSR_ANYCRLF \fB/\fP PCRE_BSR_UNICODE .sp The modifiers that are enclosed in angle brackets are literal strings as shown, including the angle brackets, but the letters within can be in either case. This example sets multiline matching with CRLF as the line ending sequence: .sp /^abc/m .sp As well as turning on the PCRE_UTF8/16 option, the \fB/8\fP modifier causes all non-printing characters in output strings to be printed using the \ex{hh...} notation. Otherwise, those less than 0x100 are output in hex without the curly brackets. .P Full details of the PCRE options are given in the .\" HREF \fBpcreapi\fP .\" documentation. . . .SS "Finding all matches in a string" .rs .sp Searching for all possible matches within each subject string can be requested by the \fB/g\fP or \fB/G\fP modifier. After finding a match, PCRE is called again to search the remainder of the subject string. The difference between \fB/g\fP and \fB/G\fP is that the former uses the \fIstartoffset\fP argument to \fBpcre[16]_exec()\fP to start searching at a new point within the entire string (which is in effect what Perl does), whereas the latter passes over a shortened substring. This makes a difference to the matching process if the pattern begins with a lookbehind assertion (including \eb or \eB). .P If any call to \fBpcre[16]_exec()\fP in a \fB/g\fP or \fB/G\fP sequence matches an empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART 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, and the normal match is retried. This imitates the way Perl handles such cases when using the \fB/g\fP modifier or the \fBsplit()\fP function. Normally, the start offset is advanced by one character, but if the newline convention recognizes CRLF as a newline, and the current character is CR followed by LF, an advance of two is used. . . .SS "Other modifiers" .rs .sp There are yet more modifiers for controlling the way \fBpcretest\fP operates. .P The \fB/+\fP modifier requests that as well as outputting the substring that matched the entire pattern, \fBpcretest\fP should in addition output the remainder of the subject string. This is useful for tests where the subject contains multiple copies of the same substring. If the \fB+\fP modifier appears twice, the same action is taken for captured substrings. In each case the remainder is output on the following line with a plus character following the capture number. Note that this modifier must not immediately follow the /S modifier because /S+ and /S++ have other meanings. .P The \fB/=\fP modifier requests that the values of all potential captured parentheses be output after a match. By default, only those up to the highest one actually used in the match are output (corresponding to the return code from \fBpcre[16]_exec()\fP). Values in the offsets vector corresponding to higher numbers should be set to -1, and these are output as "". This modifier gives a way of checking that this is happening. .P The \fB/B\fP modifier is a debugging feature. It requests that \fBpcretest\fP output a representation of the compiled code after compilation. Normally this information contains length and offset values; however, if \fB/Z\fP is also present, this data is replaced by spaces. This is a special feature for use in the automatic test scripts; it ensures that the same output is generated for different internal link sizes. .P The \fB/D\fP modifier is a PCRE debugging feature, and is equivalent to \fB/BI\fP, that is, both the \fB/B\fP and the \fB/I\fP modifiers. .P The \fB/F\fP modifier causes \fBpcretest\fP to flip the byte order of the 2-byte and 4-byte fields in the compiled pattern. This facility is for testing the feature in PCRE that allows it to execute patterns that were compiled on a host with a different endianness. This feature is not available when the POSIX interface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is specified. See also the section about saving and reloading compiled patterns below. .P The \fB/I\fP modifier requests that \fBpcretest\fP output information about the compiled pattern (whether it is anchored, has a fixed first character, and so on). It does this by calling \fBpcre[16]_fullinfo()\fP after compiling a pattern. If the pattern is studied, the results of that are also output. .P The \fB/K\fP modifier requests \fBpcretest\fP to show names from backtracking control verbs that are returned from calls to \fBpcre[16]_exec()\fP. It causes \fBpcretest\fP to create a \fBpcre[16]_extra\fP block if one has not already been created by a call to \fBpcre[16]_study()\fP, and to set the PCRE_EXTRA_MARK flag and the \fBmark\fP field within it, every time that \fBpcre[16]_exec()\fP is called. If the variable that the \fBmark\fP field points to is non-NULL for a match, non-match, or partial match, \fBpcretest\fP prints the string to which it points. For a match, this is shown on a line by itself, tagged with "MK:". For a non-match it is added to the message. .P The \fB/L\fP modifier must be followed directly by the name of a locale, for example, .sp /pattern/Lfr_FR .sp For this reason, it must be the last modifier. The given locale is set, \fBpcre[16]_maketables()\fP is called to build a set of character tables for the locale, and this is then passed to \fBpcre[16]_compile()\fP when compiling the regular expression. Without an \fB/L\fP (or \fB/T\fP) modifier, NULL is passed as the tables pointer; that is, \fB/L\fP applies only to the expression on which it appears. .P The \fB/M\fP modifier causes the size in bytes of the memory block used to hold the compiled pattern to be output. This does not include the size of the \fBpcre[16]\fP block; it is just the actual compiled data. If the pattern is successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the JIT compiled code is also output. .P If the \fB/S\fP modifier appears once, it causes \fBpcre[16]_study()\fP to be called after the expression has been compiled, and the results used when the expression is matched. If \fB/S\fP appears twice, it suppresses studying, even if it was requested externally by the \fB-s\fP command line option. This makes it possible to specify that certain patterns are always studied, and others are never studied, independently of \fB-s\fP. This feature is used in the test files in a few cases where the output is different when the pattern is studied. .P If the \fB/S\fP modifier is immediately followed by a + character, the call to \fBpcre[16]_study()\fP is made with all the JIT study options, requesting just-in-time optimization support if it is available, for both normal and partial matching. If you want to restrict the JIT compiling modes, you can follow \fB/S+\fP with a digit in the range 1 to 7: .sp 1 normal match only 2 soft partial match only 3 normal match and soft partial match 4 hard partial match only 6 soft and hard partial match 7 all three modes (default) .sp If \fB/S++\fP is used instead of \fB/S+\fP (with or without a following digit), the text "(JIT)" is added to the first output line after a match or no match when JIT-compiled code was actually used. .P Note that there is also an independent \fB/+\fP modifier; it must not be given immediately after \fB/S\fP or \fB/S+\fP because this will be misinterpreted. .P If JIT studying is successful, the compiled JIT code will automatically be used when \fBpcre[16]_exec()\fP is run, except when incompatible run-time options are specified. For more details, see the .\" HREF \fBpcrejit\fP .\" documentation. See also the \fB\eJ\fP escape sequence below for a way of setting the size of the JIT stack. .P The \fB/T\fP modifier must be followed by a single digit. It causes a specific set of built-in character tables to be passed to \fBpcre[16]_compile()\fP. It is used in the standard PCRE tests to check behaviour with different character tables. The digit specifies the tables as follows: .sp 0 the default ASCII tables, as distributed in pcre_chartables.c.dist 1 a set of tables defining ISO 8859 characters .sp In table 1, some characters whose codes are greater than 128 are identified as letters, digits, spaces, etc. . . .SS "Using the POSIX wrapper API" .rs .sp The \fB/P\fP modifier causes \fBpcretest\fP to call PCRE via the POSIX wrapper API rather than its native API. This supports only the 8-bit library. When \fB/P\fP is set, the following modifiers set options for the \fBregcomp()\fP function: .sp /i REG_ICASE /m REG_NEWLINE /N REG_NOSUB /s REG_DOTALL ) /U REG_UNGREEDY ) These options are not part of /W REG_UCP ) the POSIX standard /8 REG_UTF8 ) .sp The \fB/+\fP modifier works as described above. All other modifiers are ignored. . . .SH "DATA LINES" .rs .sp Before each data line is passed to \fBpcre[16]_exec()\fP, leading and trailing white space is removed, and it is then scanned for \e escapes. Some of these are pretty esoteric features, intended for checking out some of the more complicated features of PCRE. If you are just testing "ordinary" regular expressions, you probably don't need any of these. The following escapes are recognized: .sp \ea alarm (BEL, \ex07) \eb backspace (\ex08) \ee escape (\ex27) \ef form feed (\ex0c) \en newline (\ex0a) .\" JOIN \eqdd set the PCRE_MATCH_LIMIT limit to dd (any number of digits) \er carriage return (\ex0d) \et tab (\ex09) \ev vertical tab (\ex0b) \ennn octal character (up to 3 octal digits); always a byte unless > 255 in UTF-8 or 16-bit mode \exhh hexadecimal byte (up to 2 hex digits) \ex{hh...} hexadecimal character (any number of hex digits) .\" JOIN \eA pass the PCRE_ANCHORED option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \eB pass the PCRE_NOTBOL option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \eCdd call pcre[16]_copy_substring() for substring dd after a successful match (number less than 32) .\" JOIN \eCname call pcre[16]_copy_named_substring() for substring "name" after a successful match (name termin- ated by next non alphanumeric character) .\" JOIN \eC+ show the current captured substrings at callout time \eC- do not supply a callout function .\" JOIN \eC!n return 1 instead of 0 when callout number n is reached .\" JOIN \eC!n!m return 1 instead of 0 when callout number n is reached for the nth time .\" JOIN \eC*n pass the number n (may be negative) as callout data; this is used as the callout return value \eD use the \fBpcre[16]_dfa_exec()\fP match function \eF only shortest match for \fBpcre[16]_dfa_exec()\fP .\" JOIN \eGdd call pcre[16]_get_substring() for substring dd after a successful match (number less than 32) .\" JOIN \eGname call pcre[16]_get_named_substring() for substring "name" after a successful match (name termin- ated by next non-alphanumeric character) .\" JOIN \eJdd set up a JIT stack of dd kilobytes maximum (any number of digits) .\" JOIN \eL call pcre[16]_get_substringlist() after a successful match .\" JOIN \eM discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings .\" JOIN \eN pass the PCRE_NOTEMPTY option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP; if used twice, pass the PCRE_NOTEMPTY_ATSTART option .\" JOIN \eOdd set the size of the output vector passed to \fBpcre[16]_exec()\fP to dd (any number of digits) .\" JOIN \eP pass the PCRE_PARTIAL_SOFT option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP; if used twice, pass the PCRE_PARTIAL_HARD option .\" JOIN \eQdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd (any number of digits) \eR pass the PCRE_DFA_RESTART option to \fBpcre[16]_dfa_exec()\fP \eS output details of memory get/free calls during matching .\" JOIN \eY pass the PCRE_NO_START_OPTIMIZE option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \eZ pass the PCRE_NOTEOL option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e? pass the PCRE_NO_UTF[8|16]_CHECK option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e>dd start the match at offset dd (optional "-"; then any number of digits); this sets the \fIstartoffset\fP argument for \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e pass the PCRE_NEWLINE_CR option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e pass the PCRE_NEWLINE_LF option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e pass the PCRE_NEWLINE_CRLF option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e pass the PCRE_NEWLINE_ANYCRLF option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e pass the PCRE_NEWLINE_ANY option to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .sp The use of \ex{hh...} is not dependent on the use of the \fB/8\fP modifier on the pattern. It is recognized always. There may be any number of hexadecimal digits inside the braces; invalid values provoke error messages. .P Note that \exhh specifies one byte rather than one character in UTF-8 mode; this makes it possible to construct invalid UTF-8 sequences for testing purposes. On the other hand, \ex{hh} is interpreted as a UTF-8 character in UTF-8 mode, generating more than one byte if the value is greater than 127. When testing the 8-bit library not in UTF-8 mode, \ex{hh} generates one byte for values less than 256, and causes an error for greater values. .P In UTF-16 mode, all 4-digit \ex{hhhh} values are accepted. This makes it possible to construct invalid UTF-16 sequences for testing purposes. .P The escapes that specify line ending sequences are literal strings, exactly as shown. No more than one newline setting should be present in any data line. .P A backslash followed by anything else just escapes the anything else. If the very last character is a backslash, it is ignored. This gives a way of passing an empty line as data, since a real empty line terminates the data input. .P The \fB\eJ\fP escape provides a way of setting the maximum stack size that is used by the just-in-time optimization code. It is ignored if JIT optimization is not being used. Providing a stack that is larger than the default 32K is necessary only for very complicated patterns. .P If \eM is present, \fBpcretest\fP calls \fBpcre[16]_exec()\fP several times, with different values in the \fImatch_limit\fP and \fImatch_limit_recursion\fP fields of the \fBpcre[16]_extra\fP data structure, until it finds the minimum numbers for each parameter that allow \fBpcre[16]_exec()\fP to complete without error. Because this is testing a specific feature of the normal interpretive \fBpcre[16]_exec()\fP execution, the use of any JIT optimization that might have been set up by the \fB/S+\fP qualifier of \fB-s+\fP option is disabled. .P The \fImatch_limit\fP number is a measure of the amount of backtracking that takes place, and checking it out can be instructive. For most simple matches, the number is quite small, but for patterns with very large numbers of matching possibilities, it can become large very quickly with increasing length of subject string. The \fImatch_limit_recursion\fP number is a measure of how much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is needed to complete the match attempt. .P When \eO is used, the value specified may be higher or lower than the size set by the \fB-O\fP command line option (or defaulted to 45); \eO applies only to the call of \fBpcre[16]_exec()\fP for the line in which it appears. .P If the \fB/P\fP modifier was present on the pattern, causing the POSIX wrapper API to be used, the only option-setting sequences that have any effect are \eB, \eN, and \eZ, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to \fBregexec()\fP. . . .SH "THE ALTERNATIVE MATCHING FUNCTION" .rs .sp By default, \fBpcretest\fP uses the standard PCRE matching function, \fBpcre[16]_exec()\fP to match each data line. PCRE also supports an alternative matching function, \fBpcre[16]_dfa_test()\fP, which operates in a different way, and has some restrictions. The differences between the two functions are described in the .\" HREF \fBpcrematching\fP .\" documentation. .P If a data line contains the \eD escape sequence, or if the command line contains the \fB-dfa\fP option, the alternative matching function is used. This function finds all possible matches at a given point. If, however, the \eF escape sequence is present in the data line, it stops after the first match is found. This is always the shortest possible match. . . .SH "DEFAULT OUTPUT FROM PCRETEST" .rs .sp This section describes the output when the normal matching function, \fBpcre[16]_exec()\fP, is being used. .P When a match succeeds, \fBpcretest\fP outputs the list of captured substrings that \fBpcre[16]_exec()\fP returns, starting with number 0 for the string that matched the whole pattern. Otherwise, it outputs "No match" when the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the partially matching substring when \fBpcre[16]_exec()\fP returns PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was inspected during the partial match; it may include characters before the actual match start if a lookbehind assertion, \eK, \eb, or \eB was involved.) For any other return, \fBpcretest\fP outputs the PCRE negative error number and a short descriptive phrase. If the error is a failed UTF string check, the offset of the start of the failing character and the reason code are also output, provided that the size of the output vector is at least two. Here is an example of an interactive \fBpcretest\fP run. .sp $ pcretest PCRE version 8.13 2011-04-30 .sp re> /^abc(\ed+)/ data> abc123 0: abc123 1: 123 data> xyz No match .sp Unset capturing substrings that are not followed by one that is set are not returned by \fBpcre[16]_exec()\fP, and are not shown by \fBpcretest\fP. In the following example, there are two capturing substrings, but when the first data line is matched, the second, unset substring is not shown. An "internal" unset substring is shown as "", as for the second data line. .sp re> /(a)|(b)/ data> a 0: a 1: a data> b 0: b 1: 2: b .sp If the strings contain any non-printing characters, they are output as \exhh escapes if the value is less than 256 and UTF mode is not set. Otherwise they are output as \ex{hh...} escapes. See below for the definition of non-printing characters. If the pattern has the \fB/+\fP modifier, the output for substring 0 is followed by the the rest of the subject string, identified by "0+" like this: .sp re> /cat/+ data> cataract 0: cat 0+ aract .sp If the pattern has the \fB/g\fP or \fB/G\fP modifier, the results of successive matching attempts are output in sequence, like this: .sp re> /\eBi(\ew\ew)/g data> Mississippi 0: iss 1: ss 0: iss 1: ss 0: ipp 1: pp .sp "No match" is output only if the first match attempt fails. Here is an example of a failure message (the offset 4 that is specified by \e>4 is past the end of the subject string): .sp re> /xyz/ data> xyz\e>4 Error -24 (bad offset value) .P If any of the sequences \fB\eC\fP, \fB\eG\fP, or \fB\eL\fP are present in a data line that is successfully matched, the substrings extracted by the convenience functions are output with C, G, or L after the string number instead of a colon. This is in addition to the normal full list. The string length (that is, the return from the extraction function) is given in parentheses after each string for \fB\eC\fP and \fB\eG\fP. .P Note that whereas patterns can be continued over several lines (a plain ">" prompt is used for continuations), data lines may not. However newlines can be included in data by means of the \en escape (or \er, \er\en, etc., depending on the newline sequence setting). . . . .SH "OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION" .rs .sp When the alternative matching function, \fBpcre[16]_dfa_exec()\fP, is used (by means of the \eD escape sequence or the \fB-dfa\fP command line option), the output consists of a list of all the matches that start at the first point in the subject where there is at least one match. For example: .sp re> /(tang|tangerine|tan)/ data> yellow tangerine\eD 0: tangerine 1: tang 2: tan .sp (Using the normal matching function on this data finds only "tang".) The longest matching string is always given first (and numbered zero). After a PCRE_ERROR_PARTIAL return, the output is "Partial match:", followed by the partially matching substring. (Note that this is the entire substring that was inspected during the partial match; it may include characters before the actual match start if a lookbehind assertion, \eK, \eb, or \eB was involved.) .P If \fB/g\fP is present on the pattern, the search for further matches resumes at the end of the longest match. For example: .sp re> /(tang|tangerine|tan)/g data> yellow tangerine and tangy sultana\eD 0: tangerine 1: tang 2: tan 0: tang 1: tan 0: tan .sp Since the matching function does not support substring capture, the escape sequences that are concerned with captured substrings are not relevant. . . .SH "RESTARTING AFTER A PARTIAL MATCH" .rs .sp When the alternative matching function has given the PCRE_ERROR_PARTIAL return, indicating that the subject partially matched the pattern, you can restart the match with additional subject data by means of the \eR escape sequence. For example: .sp re> /^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$/ data> 23ja\eP\eD Partial match: 23ja data> n05\eR\eD 0: n05 .sp For further information about partial matching, see the .\" HREF \fBpcrepartial\fP .\" documentation. . . .SH CALLOUTS .rs .sp If the pattern contains any callout requests, \fBpcretest\fP's callout function is called during matching. This works with both matching functions. By default, the called function displays the callout number, the start and current positions in the text at the callout time, and the next pattern item to be tested. For example: .sp --->pqrabcdef 0 ^ ^ \ed .sp This output indicates that callout number 0 occurred for a match attempt starting at the fourth character of the subject string, when the pointer was at the seventh character of the data, and when the next pattern item was \ed. Just one circumflex is output if the start and current positions are the same. .P Callouts numbered 255 are assumed to be automatic callouts, inserted as a result of the \fB/C\fP pattern modifier. In this case, instead of showing the callout number, the offset in the pattern, preceded by a plus, is output. For example: .sp re> /\ed?[A-E]\e*/C data> E* --->E* +0 ^ \ed? +3 ^ [A-E] +8 ^^ \e* +10 ^ ^ 0: E* .sp If a pattern contains (*MARK) items, an additional line is output whenever a change of latest mark is passed to the callout function. For example: .sp re> /a(*MARK:X)bc/C data> abc --->abc +0 ^ a +1 ^^ (*MARK:X) +10 ^^ b Latest Mark: X +11 ^ ^ c +12 ^ ^ 0: abc .sp The mark changes between matching "a" and "b", but stays the same for the rest of the match, so nothing more is output. If, as a result of backtracking, the mark reverts to being unset, the text "" is output. .P The callout function in \fBpcretest\fP returns zero (carry on matching) by default, but you can use a \eC item in a data line (as described above) to change this and other parameters of the callout. .P Inserting callouts can be helpful when using \fBpcretest\fP to check complicated regular expressions. For further information about callouts, see the .\" HREF \fBpcrecallout\fP .\" documentation. . . . .SH "NON-PRINTING CHARACTERS" .rs .sp When \fBpcretest\fP is outputting text in the compiled version of a pattern, bytes other than 32-126 are always treated as non-printing characters are are therefore shown as hex escapes. .P When \fBpcretest\fP is outputting text that is a matched part of a subject string, it behaves in the same way, unless a different locale has been set for the pattern (using the \fB/L\fP modifier). In this case, the \fBisprint()\fP function to distinguish printing and non-printing characters. . . . .SH "SAVING AND RELOADING COMPILED PATTERNS" .rs .sp The facilities described in this section are not available when the POSIX interface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is specified. .P When the POSIX interface is not in use, you can cause \fBpcretest\fP to write a compiled pattern to a file, by following the modifiers with > and a file name. For example: .sp /pattern/im >/some/file .sp See the .\" HREF \fBpcreprecompile\fP .\" documentation for a discussion about saving and re-using compiled patterns. Note that if the pattern was successfully studied with JIT optimization, the JIT data cannot be saved. .P The data that is written is binary. The first eight bytes are the length of the compiled pattern data followed by the length of the optional study data, each written as four bytes in big-endian order (most significant byte first). If there is no study data (either the pattern was not studied, or studying did not return any data), the second length is zero. The lengths are followed by an exact copy of the compiled pattern. If there is additional study data, this (excluding any JIT data) follows immediately after the compiled pattern. After writing the file, \fBpcretest\fP expects to read a new pattern. .P A saved pattern can be reloaded into \fBpcretest\fP by specifying < and a file name instead of a pattern. The name of the file must not contain a < character, as otherwise \fBpcretest\fP will interpret the line as a pattern delimited by < characters. For example: .sp re> .PP .SM .B int pcre_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); .PP .B int pcre16_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," .ti +5n .B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); . .SH DESCRIPTION .rs .sp This function matches a compiled regular expression against a given subject string, using a matching algorithm that is similar to Perl's. It returns offsets to captured substrings. Its arguments are: .sp \fIcode\fP Points to the compiled pattern \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure, or is NULL \fIsubject\fP Points to the subject string \fIlength\fP Length of the subject string, in bytes \fIstartoffset\fP Offset in bytes in the subject at which to start matching \fIoptions\fP Option bits \fIovector\fP Points to a vector of ints for result offsets \fIovecsize\fP Number of elements in the vector (a multiple of 3) .sp The options are: .sp PCRE_ANCHORED Match only at the first position PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF PCRE_BSR_UNICODE \eR matches all Unicode line endings PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, & CRLF as newline sequences PCRE_NEWLINE_CR Recognize CR as the only newline sequence PCRE_NEWLINE_CRLF Recognize CRLF as the only newline sequence PCRE_NEWLINE_LF Recognize LF as the only newline sequence PCRE_NOTBOL Subject string is not the beginning of a line PCRE_NOTEOL Subject string is not the end of a line PCRE_NOTEMPTY An empty string is not a valid match PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject is not a valid match PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16 validity (only relevant if PCRE_UTF16 was set at compile time) PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8 validity (only relevant if PCRE_UTF8 was set at compile time) PCRE_PARTIAL ) Return PCRE_ERROR_PARTIAL for a partial PCRE_PARTIAL_SOFT ) match if no full matches are found PCRE_PARTIAL_HARD Return PCRE_ERROR_PARTIAL for a partial match if that is found before a full match .sp For details of partial matching, see the .\" HREF \fBpcrepartial\fP .\" page. A \fBpcre_extra\fP structure contains the following fields: .sp \fIflags\fP Bits indicating which fields are set \fIstudy_data\fP Opaque data from \fBpcre[16]_study()\fP \fImatch_limit\fP Limit on internal resource use \fImatch_limit_recursion\fP Limit on internal recursion depth \fIcallout_data\fP Opaque data passed back to callouts \fItables\fP Points to character tables or is NULL \fImark\fP For passing back a *MARK pointer \fIexecutable_jit\fP Opaque data from JIT compilation .sp The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcrecallout.30000644000222100022210000002063011735643053012461 00000000000000.TH PCRECALLOUT 3 "08 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE CALLOUTS" .rs .sp .B int (*pcre_callout)(pcre_callout_block *); .PP .B int (*pcre16_callout)(pcre16_callout_block *); .PP PCRE provides a feature called "callout", which is a means of temporarily passing control to the caller of PCRE in the middle of pattern matching. The caller of PCRE provides an external function by putting its entry point in the global variable \fIpcre_callout\fP (\fIpcre16_callout\fP for the 16-bit library). By default, this variable contains NULL, which disables all calling out. .P Within a regular expression, (?C) indicates the points at which the external function is to be called. Different callout points can be identified by putting a number less than 256 after the letter C. The default value is zero. For example, this pattern has two callout points: .sp (?C1)abc(?C2)def .sp If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled, PCRE automatically inserts callouts, all with number 255, before each item in the pattern. For example, if PCRE_AUTO_CALLOUT is used with the pattern .sp A(\ed{2}|--) .sp it is processed as if it were .sp (?C255)A(?C255)((?C255)\ed{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) .sp Notice that there is a callout before and after each parenthesis and alternation bar. Automatic callouts can be used for tracking the progress of pattern matching. The .\" HREF \fBpcretest\fP .\" command has an option that sets automatic callouts; when it is used, the output indicates how the pattern is matched. This is useful information when you are trying to optimize the performance of a particular pattern. .P The use of callouts in a pattern makes it ineligible for optimization by the just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE option always fails. . . .SH "MISSING CALLOUTS" .rs .sp You should be aware that, because of optimizations in the way PCRE matches patterns by default, callouts sometimes do not happen. For example, if the pattern is .sp ab(?C4)cd .sp PCRE knows that any matching string must contain the letter "d". If the subject string is "abyz", the lack of "d" means that matching doesn't ever start, and the callout is never reached. However, with "abyd", though the result is still no match, the callout is obeyed. .P If the pattern is studied, PCRE knows the minimum length of a matching string, and will immediately give a "no match" return without actually running a match if the subject is not long enough, or, for unanchored patterns, if it has been scanned far enough. .P You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE option to the matching function, or by starting the pattern with (*NO_START_OPT). This slows down the matching process, but does ensure that callouts such as the example above are obeyed. . . .SH "THE CALLOUT INTERFACE" .rs .sp During matching, when PCRE reaches a callout point, the external function defined by \fIpcre_callout\fP or \fIpcre16_callout\fP is called (if it is set). This applies to both normal and DFA matching. The only argument to the callout function is a pointer to a \fBpcre_callout\fP or \fBpcre16_callout\fP block. These structures contains the following fields: .sp int \fIversion\fP; int \fIcallout_number\fP; int *\fIoffset_vector\fP; const char *\fIsubject\fP; (8-bit version) PCRE_SPTR16 \fIsubject\fP; (16-bit version) int \fIsubject_length\fP; int \fIstart_match\fP; int \fIcurrent_position\fP; int \fIcapture_top\fP; int \fIcapture_last\fP; void *\fIcallout_data\fP; int \fIpattern_position\fP; int \fInext_item_length\fP; const unsigned char *\fImark\fP; (8-bit version) const PCRE_UCHAR16 *\fImark\fP; (16-bit version) .sp The \fIversion\fP field is an integer containing the version number of the block format. The initial version was 0; the current version is 2. The version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields. .P The \fIcallout_number\fP field contains the number of the callout, as compiled into the pattern (that is, the number after ?C for manual callouts, and 255 for automatically generated callouts). .P The \fIoffset_vector\fP field is a pointer to the vector of offsets that was passed by the caller to the matching function. When \fBpcre_exec()\fP or \fBpcre16_exec()\fP is used, the contents can be inspected, in order to extract substrings that have been matched so far, in the same way as for extracting substrings after a match has completed. For the DFA matching functions, this field is not useful. .P The \fIsubject\fP and \fIsubject_length\fP fields contain copies of the values that were passed to the matching function. .P The \fIstart_match\fP field normally contains the offset within the subject at which the current match attempt started. However, if the escape sequence \eK has been encountered, this value is changed to reflect the modified starting point. If the pattern is not anchored, the callout function may be called several times from the same point in the pattern for different starting points in the subject. .P The \fIcurrent_position\fP field contains the offset within the subject of the current match pointer. .P When the \fBpcre_exec()\fP or \fBpcre16_exec()\fP is used, the \fIcapture_top\fP field contains one more than the number of the highest numbered captured substring so far. If no substrings have been captured, the value of \fIcapture_top\fP is one. This is always the case when the DFA functions are used, because they do not support captured substrings. .P The \fIcapture_last\fP field contains the number of the most recently captured substring. If no substrings have been captured, its value is -1. This is always the case for the DFA matching functions. .P The \fIcallout_data\fP field contains a value that is passed to a matching function specifically so that it can be passed back in callouts. It is passed in the \fIcallout_data\fP field of a \fBpcre_extra\fP or \fBpcre16_extra\fP data structure. If no such data was passed, the value of \fIcallout_data\fP in a callout block is NULL. There is a description of the \fBpcre_extra\fP structure in the .\" HREF \fBpcreapi\fP .\" documentation. .P The \fIpattern_position\fP field is present from version 1 of the callout structure. It contains the offset to the next item to be matched in the pattern string. .P The \fInext_item_length\fP field is present from version 1 of the callout structure. It contains the length of the next item to be matched in the pattern string. When the callout immediately precedes an alternation bar, a closing parenthesis, or the end of the pattern, the length is zero. When the callout precedes an opening parenthesis, the length is that of the entire subpattern. .P The \fIpattern_position\fP and \fInext_item_length\fP fields are intended to help in distinguishing between different automatic callouts, which all have the same callout number. However, they are set for all callouts. .P The \fImark\fP field is present from version 2 of the callout structure. In callouts from \fBpcre_exec()\fP or \fBpcre16_exec()\fP it contains a pointer to the zero-terminated name of the most recently passed (*MARK), (*PRUNE), or (*THEN) item in the match, or NULL if no such items have been passed. Instances of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In callouts from the DFA matching functions this field always contains NULL. . . .SH "RETURN VALUES" .rs .sp The external callout function returns an integer to PCRE. If the value is zero, matching proceeds as normal. If the value is greater than zero, matching fails at the current point, but the testing of other matching possibilities goes ahead, just as if a lookahead assertion had failed. If the value is less than zero, the match is abandoned, the matching function returns the negative value. .P Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a standard "no match" failure. The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions; it will never be used by PCRE itself. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 08 Janurary 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_copy_substring.30000644000222100022210000000250011735631212014215 00000000000000.TH PCRE_COPY_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, .ti +5n .B int \fIbuffersize\fP); .PP .B int pcre16_copy_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP, .ti +5n .B int \fIbuffersize\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for extracting a captured substring into a given buffer. The arguments are: .sp \fIsubject\fP Subject that has been successfully matched \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringnumber\fP Number of the required substring \fIbuffer\fP Buffer to receive the string \fIbuffersize\fP Size of buffer .sp The yield is the length of the string, PCRE_ERROR_NOMEMORY if the buffer was too small, or PCRE_ERROR_NOSUBSTRING if the string number is invalid. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcresyntax.30000644000222100022210000002752111760163326012350 00000000000000.TH PCRESYNTAX 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE REGULAR EXPRESSION SYNTAX SUMMARY" .rs .sp The full syntax and semantics of the regular expressions that are supported by PCRE are described in the .\" HREF \fBpcrepattern\fP .\" documentation. This document contains a quick-reference summary of the syntax. . . .SH "QUOTING" .rs .sp \ex where x is non-alphanumeric is a literal x \eQ...\eE treat enclosed characters as literal . . .SH "CHARACTERS" .rs .sp \ea alarm, that is, the BEL character (hex 07) \ecx "control-x", where x is any ASCII character \ee escape (hex 1B) \ef form feed (hex 0C) \en newline (hex 0A) \er carriage return (hex 0D) \et tab (hex 09) \eddd character with octal code ddd, or backreference \exhh character with hex code hh \ex{hhh..} character with hex code hhh.. . . .SH "CHARACTER TYPES" .rs .sp . any character except newline; in dotall mode, any character whatsoever \eC one data unit, even in UTF mode (best avoided) \ed a decimal digit \eD a character that is not a decimal digit \eh a horizontal white space character \eH a character that is not a horizontal white space character \eN a character that is not a newline \ep{\fIxx\fP} a character with the \fIxx\fP property \eP{\fIxx\fP} a character without the \fIxx\fP property \eR a newline sequence \es a white space character \eS a character that is not a white space character \ev a vertical white space character \eV a character that is not a vertical white space character \ew a "word" character \eW a "non-word" character \eX an extended Unicode sequence .sp In PCRE, by default, \ed, \eD, \es, \eS, \ew, and \eW recognize only ASCII characters, even in a UTF mode. However, this can be changed by setting the PCRE_UCP option. . . .SH "GENERAL CATEGORY PROPERTIES FOR \ep and \eP" .rs .sp C Other Cc Control Cf Format Cn Unassigned Co Private use Cs Surrogate .sp L Letter Ll Lower case letter Lm Modifier letter Lo Other letter Lt Title case letter Lu Upper case letter L& Ll, Lu, or Lt .sp M Mark Mc Spacing mark Me Enclosing mark Mn Non-spacing mark .sp N Number Nd Decimal number Nl Letter number No Other number .sp P Punctuation Pc Connector punctuation Pd Dash punctuation Pe Close punctuation Pf Final punctuation Pi Initial punctuation Po Other punctuation Ps Open punctuation .sp S Symbol Sc Currency symbol Sk Modifier symbol Sm Mathematical symbol So Other symbol .sp Z Separator Zl Line separator Zp Paragraph separator Zs Space separator . . .SH "PCRE SPECIAL CATEGORY PROPERTIES FOR \ep and \eP" .rs .sp Xan Alphanumeric: union of properties L and N Xps POSIX space: property Z or tab, NL, VT, FF, CR Xsp Perl space: property Z or tab, NL, FF, CR Xwd Perl word: property Xan or underscore . . .SH "SCRIPT NAMES FOR \ep AND \eP" .rs .sp Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi. . . .SH "CHARACTER CLASSES" .rs .sp [...] positive character class [^...] negative character class [x-y] range (can be used for hex characters) [[:xxx:]] positive POSIX named set [[:^xxx:]] negative POSIX named set .sp alnum alphanumeric alpha alphabetic ascii 0-127 blank space or tab cntrl control character digit decimal digit graph printing, excluding space lower lower case letter print printing, including space punct printing, excluding alphanumeric space white space upper upper case letter word same as \ew xdigit hexadecimal digit .sp In PCRE, POSIX character set names recognize only ASCII characters by default, but some of them use Unicode properties if PCRE_UCP is set. You can use \eQ...\eE inside a character class. . . .SH "QUANTIFIERS" .rs .sp ? 0 or 1, greedy ?+ 0 or 1, possessive ?? 0 or 1, lazy * 0 or more, greedy *+ 0 or more, possessive *? 0 or more, lazy + 1 or more, greedy ++ 1 or more, possessive +? 1 or more, lazy {n} exactly n {n,m} at least n, no more than m, greedy {n,m}+ at least n, no more than m, possessive {n,m}? at least n, no more than m, lazy {n,} n or more, greedy {n,}+ n or more, possessive {n,}? n or more, lazy . . .SH "ANCHORS AND SIMPLE ASSERTIONS" .rs .sp \eb word boundary \eB not a word boundary ^ start of subject also after internal newline in multiline mode \eA start of subject $ end of subject also before newline at end of subject also before internal newline in multiline mode \eZ end of subject also before newline at end of subject \ez end of subject \eG first matching position in subject . . .SH "MATCH POINT RESET" .rs .sp \eK reset start of match . . .SH "ALTERNATION" .rs .sp expr|expr|expr... . . .SH "CAPTURING" .rs .sp (...) capturing group (?...) named capturing group (Perl) (?'name'...) named capturing group (Perl) (?P...) named capturing group (Python) (?:...) non-capturing group (?|...) non-capturing group; reset group numbers for capturing groups in each alternative . . .SH "ATOMIC GROUPS" .rs .sp (?>...) atomic, non-capturing group . . . . .SH "COMMENT" .rs .sp (?#....) comment (not nestable) . . .SH "OPTION SETTING" .rs .sp (?i) caseless (?J) allow duplicate names (?m) multiline (?s) single line (dotall) (?U) default ungreedy (lazy) (?x) extended (ignore white space) (?-...) unset option(s) .sp The following are recognized only at the start of a pattern or after one of the newline-setting options with similar syntax: .sp (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) (*UCP) set PCRE_UCP (use Unicode properties for \ed etc) . . .SH "LOOKAHEAD AND LOOKBEHIND ASSERTIONS" .rs .sp (?=...) positive look ahead (?!...) negative look ahead (?<=...) positive look behind (? reference by name (Perl) \ek'name' reference by name (Perl) \eg{name} reference by name (Perl) \ek{name} reference by name (.NET) (?P=name) reference by name (Python) . . .SH "SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)" .rs .sp (?R) recurse whole pattern (?n) call subpattern by absolute number (?+n) call subpattern by relative number (?-n) call subpattern by relative number (?&name) call subpattern by name (Perl) (?P>name) call subpattern by name (Python) \eg call subpattern by name (Oniguruma) \eg'name' call subpattern by name (Oniguruma) \eg call subpattern by absolute number (Oniguruma) \eg'n' call subpattern by absolute number (Oniguruma) \eg<+n> call subpattern by relative number (PCRE extension) \eg'+n' call subpattern by relative number (PCRE extension) \eg<-n> call subpattern by relative number (PCRE extension) \eg'-n' call subpattern by relative number (PCRE extension) . . .SH "CONDITIONAL PATTERNS" .rs .sp (?(condition)yes-pattern) (?(condition)yes-pattern|no-pattern) .sp (?(n)... absolute reference condition (?(+n)... relative reference condition (?(-n)... relative reference condition (?()... named reference condition (Perl) (?('name')... named reference condition (Perl) (?(name)... named reference condition (PCRE) (?(R)... overall recursion condition (?(Rn)... specific group recursion condition (?(R&name)... specific recursion condition (?(DEFINE)... define subpattern for reference (?(assert)... assertion condition . . .SH "BACKTRACKING CONTROL" .rs .sp The following act immediately they are reached: .sp (*ACCEPT) force successful match (*FAIL) force backtrack; synonym (*F) (*MARK:NAME) set name to be passed back; synonym (*:NAME) .sp The following act only when a subsequent match failure causes a backtrack to reach them. They all force a match failure, but they differ in what happens afterwards. Those that advance the start-of-match point do so only if the pattern is not anchored. .sp (*COMMIT) overall failure, no advance of starting point (*PRUNE) advance to next starting character (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE) (*SKIP) advance to current matching position (*SKIP:NAME) advance to position corresponding to an earlier (*MARK:NAME); if not found, the (*SKIP) is ignored (*THEN) local failure, backtrack to next alternation (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN) . . .SH "NEWLINE CONVENTIONS" .rs .sp These are recognized only at the very start of the pattern or after a (*BSR_...), (*UTF8), (*UTF16) or (*UCP) option. .sp (*CR) carriage return only (*LF) linefeed only (*CRLF) carriage return followed by linefeed (*ANYCRLF) all three of the above (*ANY) any Unicode newline sequence . . .SH "WHAT \eR MATCHES" .rs .sp These are recognized only at the very start of the pattern or after a (*...) option that sets the newline convention or a UTF or UCP mode. .sp (*BSR_ANYCRLF) CR, LF, or CRLF (*BSR_UNICODE) any Unicode newline sequence . . .SH "CALLOUTS" .rs .sp (?C) callout (?Cn) callout with data n . . .SH "SEE ALSO" .rs .sp \fBpcrepattern\fP(3), \fBpcreapi\fP(3), \fBpcrecallout\fP(3), \fBpcrematching\fP(3), \fBpcre\fP(3). . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcrestack.30000644000222100022210000002122211735643440012121 00000000000000.TH PCRESTACK 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE DISCUSSION OF STACK USAGE" .rs .sp When you call \fBpcre[16]_exec()\fP, it makes use of an internal function called \fBmatch()\fP. 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 proceeds deeper and deeper into the tree of possibilities, the recursion depth increases. The \fBmatch()\fP function is also called in other circumstances, for example, whenever a parenthesized sub-pattern is entered, and in certain cases of repetition. .P Not all calls of \fBmatch()\fP 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. .P The above comments apply when \fBpcre[16]_exec()\fP is run in its normal interpretive manner. If the pattern was studied with the PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was successful, and the options passed to \fBpcre[16]_exec()\fP were not incompatible, the matching process uses the JIT-compiled code instead of the \fBmatch()\fP function. In this case, the memory requirements are handled entirely differently. See the .\" HREF \fBpcrejit\fP .\" documentation for details. .P The \fBpcre[16]_dfa_exec()\fP function operates in an entirely different way, and uses recursion only when there is a regular expression recursion or subroutine call in the pattern. This includes the processing of assertion and "once-only" subpatterns, which are handled like subroutine calls. Normally, these are never very deep, and the limit on the complexity of \fBpcre[16]_dfa_exec()\fP is controlled by the amount of workspace it is given. However, it is possible to write patterns with runaway infinite recursions; such patterns will cause \fBpcre[16]_dfa_exec()\fP to run out of stack. At present, there is no protection against this. .P The comments that follow do NOT apply to \fBpcre[16]_dfa_exec()\fP; they are relevant only for \fBpcre[16]_exec()\fP without the JIT optimization. . . .SS "Reducing \fBpcre[16]_exec()\fP's stack usage" .rs .sp Each time that \fBmatch()\fP 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 therefore the amount of stack used, by modifying the pattern that is being matched. Consider, for example, this pattern: .sp ([^<]|<(?!inet))+ .sp It matches from wherever it starts until it encounters " .\" section on extra data for \fBpcre[16]_exec()\fP .\" in the .\" HREF \fBpcreapi\fP .\" documentation. .P 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. .P In Unix-like environments, the \fBpcretest\fP test program has a command line option (\fB-S\fP) that can be used to increase the size of its stack. As long as the stack is large enough, another option (\fB-M\fP) can be used to find the smallest limits that allow a particular pattern to match a given subject string. This is done by calling \fBpcre[16]_exec()\fP repeatedly with different limits. . . .SS "Obtaining an estimate of stack usage" .rs .sp The actual amount of stack used per recursion can vary quite a lot, depending on the compiler that was used to build PCRE and the optimization or debugging options that were set for it. The rule of thumb value of 500 bytes mentioned above may be larger or smaller than what is actually needed. A better approximation can be obtained by running this command: .sp pcretest -m -C .sp The \fB-C\fP option causes \fBpcretest\fP to output information about the options with which PCRE was compiled. When \fB-m\fP is also given (before \fB-C\fP), information about stack use is given in a line like this: .sp Match recursion uses stack: approximate frame size = 640 bytes .sp The value is approximate because some recursions need a bit more (up to perhaps 16 more bytes). .P If the above command is given when PCRE is compiled to use the heap instead of the stack for recursion, the value that is output is the size of each block that is obtained from the heap. . . .SS "Changing stack size in Unix-like systems" .rs .sp In Unix-like environments, there is not often a problem with the stack unless very long strings are involved, 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: .sp ulimit -s .sp Unfortunately, the effect of running out of stack is often SIGSEGV, though sometimes a more explicit error message is given. You can normally increase the limit on stack size by code such as this: .sp struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); rlim.rlim_cur = 100*1024*1024; setrlimit(RLIMIT_STACK, &rlim); .sp This reads the current limits (soft and hard) using \fBgetrlimit()\fP, then attempts to increase the soft limit to 100Mb using \fBsetrlimit()\fP. You must do this before calling \fBpcre[16]_exec()\fP. . . .SS "Changing stack size in Mac OS X" .rs .sp Using \fBsetrlimit()\fP, as described above, should also work on Mac OS X. It is also possible to set a stack size when linking a program. There is a discussion about stack sizes in Mac OS X at this web site: .\" HTML .\" http://developer.apple.com/qa/qa2005/qa1419.html. .\" . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 21 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre-config.txt0000644000222100022210000000553211775533017013023 00000000000000PCRE-CONFIG(1) PCRE-CONFIG(1) NAME pcre-config - program to return PCRE configuration SYNOPSIS pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs16] [--libs-cpp] [--libs-posix] [--cflags] [--cflags-posix] DESCRIPTION pcre-config returns the configuration of the installed PCRE libraries and the options required to compile a program to use them. Some of the options apply only to the 8-bit or 16-bit libraries, respectively, and are not available if only one of those libraries has been built. If an unavailable option is encountered, the "usage" information is output. OPTIONS --prefix Writes the directory prefix used in the PCRE installation for architecture independent files (/usr on many systems, /usr/local on some systems) to the standard output. --exec-prefix Writes the directory prefix used in the PCRE installation for architecture dependent files (normally the same as --prefix) to the standard output. --version Writes the version number of the installed PCRE libraries to the standard output. --libs Writes to the standard output the command line options required to link with the 8-bit PCRE library (-lpcre on many systems). --libs16 Writes to the standard output the command line options required to link with the 16-bit PCRE library (-lpcre16 on many systems). --libs-cpp Writes to the standard output the command line options required to link with PCRE's C++ wrapper library (-lpcrecpp -lpcre on many systems). --libs-posix Writes to the standard output the command line options required to link with PCRE's POSIX API wrapper library (-lpcreposix -lpcre on many systems). --cflags Writes to the standard output the command line options required to compile files that use PCRE (this may include some -I options, but is blank on many systems). --cflags-posix Writes to the standard output the command line options required to compile files that use PCRE's POSIX API wrapper library (this may include some -I options, but is blank on many systems). SEE ALSO pcre(3) AUTHOR This manual page was originally written by Mark Baker for the Debian GNU/Linux system. It has been subsequently revised as a generic PCRE man page. REVISION Last updated: 01 January 2012 pcre-8.31/doc/pcre_study.30000644000222100022210000000265111735631643012332 00000000000000.TH PCRE_STUDY 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP); .PP .B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP); . .SH DESCRIPTION .rs .sp This function studies a compiled pattern, to see if additional information can be extracted that might speed up matching. Its arguments are: .sp \fIcode\fP A compiled regular expression \fIoptions\fP Options for \fBpcre[16]_study()\fP \fIerrptr\fP Where to put an error message .sp If the function succeeds, it returns a value that can be passed to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP via their \fIextra\fP arguments. .P If the function returns NULL, either it could not find any additional information, or there was an error. You can tell the difference by looking at the error value. It is NULL in first case. .P The only option is PCRE_STUDY_JIT_COMPILE. It requests just-in-time compilation if possible. If PCRE has been compiled without JIT support, this option is ignored. See the .\" HREF \fBpcrejit\fP .\" page for further details. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcrematching.30000644000222100022210000002130111735643230012601 00000000000000.TH PCREMATCHING 3 "08 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE MATCHING ALGORITHMS" .rs .sp This document describes the two different algorithms that are available in PCRE for matching a compiled regular expression against a given subject string. The "standard" algorithm is the one provided by the \fBpcre_exec()\fP and \fBpcre16_exec()\fP functions. These work in the same was as Perl's matching function, and provide a Perl-compatible matching operation. The just-in-time (JIT) optimization that is described in the .\" HREF \fBpcrejit\fP .\" documentation is compatible with these functions. .P An alternative algorithm is provided by the \fBpcre_dfa_exec()\fP and \fBpcre16_dfa_exec()\fP functions; they operate in a different way, and are not Perl-compatible. This alternative has advantages and disadvantages compared with the standard algorithm, and these are described below. .P When there is only one possible way in which a given subject string can match a pattern, the two algorithms give the same answer. A difference arises, however, when there are multiple possibilities. For example, if the pattern .sp ^<.*> .sp is matched against the string .sp .sp there are three possible answers. The standard algorithm finds only one of them, whereas the alternative algorithm finds all three. . . .SH "REGULAR EXPRESSIONS AS TREES" .rs .sp The set of strings that are matched by a regular expression can be represented 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 ways to search a tree: depth-first and breadth-first, and these correspond to the two matching algorithms provided by PCRE. . . .SH "THE STANDARD MATCHING ALGORITHM" .rs .sp In the terminology of Jeffrey Friedl's book "Mastering Regular Expressions", the standard algorithm is an "NFA algorithm". It conducts a depth-first search of the pattern tree. That is, it proceeds along a single path through the tree, checking that the subject matches what is required. When there is a mismatch, the algorithm tries any alternatives at the current point, and if they all fail, it backs up to the previous branch point in the tree, and tries the next alternative branch at that level. This often involves backing up (moving to the left) in the subject string as well. The order in which repetition branches are tried is controlled by the greedy or ungreedy nature of the quantifier. .P If a leaf node is reached, a matching string has been found, and at that point the algorithm stops. Thus, if there is more than one possible match, this algorithm returns the first one that it finds. Whether this is the shortest, the longest, or some intermediate length depends on the way the greedy and ungreedy repetition quantifiers are specified in the pattern. .P Because it ends up with a single path through the tree, it is relatively straightforward for this algorithm to keep track of the substrings that are matched by portions of the pattern in parentheses. This provides support for capturing parentheses and back references. . . .SH "THE ALTERNATIVE MATCHING ALGORITHM" .rs .sp This algorithm conducts a breadth-first search of the tree. Starting from the first matching point in the subject, it scans the subject string from left to right, once, character by character, and as it does this, it remembers all the paths through the tree that represent valid matches. In Friedl's terminology, this is a kind of "DFA algorithm", though it is not implemented as a traditional finite state machine (it keeps multiple states active simultaneously). .P Although the general principle of this matching algorithm is that it scans the subject string only once, without backtracking, there is one exception: when a lookaround assertion is encountered, the characters following or preceding the current point have to be independently inspected. .P The scan continues until either the end of the subject is reached, or there are no more unterminated paths. At this point, terminated paths represent the different matching possibilities (if there are none, the match has failed). Thus, if there is more than one possible match, this algorithm finds all of them, and in particular, it finds the longest. The matches are returned in decreasing order of length. There is an option to stop the algorithm after the first match (which is necessarily the shortest) is found. .P Note that all the matches that are found start at the same point in the subject. If the pattern .sp cat(er(pillar)?)? .sp is matched against the string "the caterpillar catchment", the result will be the three strings "caterpillar", "cater", and "cat" that start at the fifth character of the subject. The algorithm does not automatically move on to find matches that start at later positions. .P There are a number of features of PCRE regular expressions that are not supported by the alternative matching algorithm. They are as follows: .P 1. Because the algorithm finds all possible matches, the greedy or ungreedy nature of repetition quantifiers is not relevant. Greedy and ungreedy quantifiers are treated in exactly the same way. However, possessive quantifiers can make a difference when what follows could also match what is quantified, for example in a pattern like this: .sp ^a++\ew! .sp This pattern matches "aaab!" but not "aaa!", which would be matched by a non-possessive quantifier. Similarly, if an atomic group is present, it is matched as if it were a standalone pattern at the current point, and the longest match is then "locked in" for the rest of the overall pattern. .P 2. When dealing with multiple paths through the tree simultaneously, it is not straightforward to keep track of captured substrings for the different matching possibilities, and PCRE's implementation of this algorithm does not attempt to do this. This means that no captured substrings are available. .P 3. Because no substrings are captured, back references within the pattern are not supported, and cause errors if encountered. .P 4. For the same reason, conditional expressions that use a backreference as the condition or test for a specific group recursion are not supported. .P 5. Because many paths through the tree may be active, the \eK escape sequence, which resets the start of the match when encountered (but may be on some paths and not on others), is not supported. It causes an error if encountered. .P 6. Callouts are supported, but the value of the \fIcapture_top\fP field is always 1, and the value of the \fIcapture_last\fP field is always -1. .P 7. The \eC escape sequence, which (in the standard algorithm) always matches a single data unit, even in UTF-8 or UTF-16 modes, is not supported in these modes, because the alternative algorithm moves through the subject string one character (not data unit) at a time, for all active paths through the tree. .P 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) are not supported. (*FAIL) is supported, and behaves like a failing negative assertion. . . .SH "ADVANTAGES OF THE ALTERNATIVE ALGORITHM" .rs .sp Using the alternative matching algorithm provides the following advantages: .P 1. All possible matches (at a single point in the subject) are automatically found, and in particular, the longest match is found. To find more than one match using the standard algorithm, you have to do kludgy things with callouts. .P 2. Because the alternative algorithm scans the subject string just once, and never needs to backtrack (except for lookbehinds), it is possible to pass very long subject strings to the matching function in several pieces, checking for partial matching each time. Although it is possible to do multi-segment matching using the standard algorithm by retaining partially matched substrings, it is more complicated. The .\" HREF \fBpcrepartial\fP .\" documentation gives details of partial matching and discusses multi-segment matching. . . .SH "DISADVANTAGES OF THE ALTERNATIVE ALGORITHM" .rs .sp The alternative algorithm suffers from a number of disadvantages: .P 1. It is substantially slower than the standard algorithm. This is partly because it has to search for all possible matches, but is also because it is less susceptible to optimization. .P 2. Capturing parentheses and back references are not supported. .P 3. Although atomic groups are supported, their use does not provide the performance advantage that it does for the standard algorithm. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 08 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_get_named_substring.30000644000222100022210000000315511735631402015176 00000000000000.TH PCRE_GET_NAMED_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_get_named_substring(const pcre *\fIcode\fP, .ti +5n .B const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B const char **\fIstringptr\fP); .PP .B int pcre16_get_named_substring(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, .ti +5n .B PCRE_SPTR16 *\fIstringptr\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for extracting a captured substring by name. The arguments are: .sp \fIcode\fP Compiled pattern \fIsubject\fP Subject that has been successfully matched \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringname\fP Name of the required substring \fIstringptr\fP Where to put the string pointer .sp The memory in which the substring is placed is obtained by calling \fBpcre[16]_malloc()\fP. The convenience function \fBpcre[16]_free_substring()\fP can be used to free it when it is no longer needed. The yield of the function is the length of the extracted substring, PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string name is invalid. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre.30000644000222100022210000001424011735630560011074 00000000000000.TH PCRE 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH INTRODUCTION .rs .sp The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl, with just a few differences. Some features that appeared in Python and PCRE before they appeared in Perl are also available using the Python syntax, there is some support for one or two .NET and Oniguruma syntax items, and there is an option for requesting some minor changes that give better JavaScript compatibility. .P Starting with release 8.30, it is possible to compile two separate PCRE libraries: the original, which supports 8-bit character strings (including UTF-8 strings), and a second library that supports 16-bit character strings (including UTF-16 strings). The build process allows either one or both to be built. The majority of the work to make this possible was done by Zoltan Herczeg. .P The two libraries contain identical sets of functions, except that the names in the 16-bit library start with \fBpcre16_\fP instead of \fBpcre_\fP. To avoid over-complication and reduce the documentation maintenance load, most of the documentation describes the 8-bit library, with the differences for the 16-bit library described separately in the .\" HREF \fBpcre16\fP .\" page. References to functions or structures of the form \fIpcre[16]_xxx\fP should be read as meaning "\fIpcre_xxx\fP when using the 8-bit library and \fIpcre16_xxx\fP when using the 16-bit library". .P The current implementation of PCRE corresponds approximately with Perl 5.12, including support for UTF-8/16 encoded strings and Unicode general category properties. However, UTF-8/16 and Unicode support has to be explicitly enabled; it is not the default. The Unicode tables correspond to Unicode release 6.0.0. .P In addition to the Perl-compatible matching function, PCRE contains an alternative function that matches the same compiled patterns in a different way. In certain circumstances, the alternative function has some advantages. For a discussion of the two matching algorithms, see the .\" HREF \fBpcrematching\fP .\" page. .P PCRE is written in C and released as a C library. A number of people have written wrappers and interfaces of various kinds. In particular, Google Inc. have provided a comprehensive C++ wrapper for the 8-bit library. This is now included as part of the PCRE distribution. The .\" HREF \fBpcrecpp\fP .\" page has details of this interface. Other people's contributions can be found in the \fIContrib\fP directory at the primary FTP site, which is: .sp .\" HTML .\" ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre .P Details of exactly which Perl regular expression features are and are not supported by PCRE are given in separate documents. See the .\" HREF \fBpcrepattern\fP .\" and .\" HREF \fBpcrecompat\fP .\" pages. There is a syntax summary in the .\" HREF \fBpcresyntax\fP .\" page. .P Some features of PCRE can be included, excluded, or changed when the library is built. The .\" HREF \fBpcre_config()\fP .\" function makes it possible for a client to discover which features are available. The features themselves are described in the .\" HREF \fBpcrebuild\fP .\" page. Documentation about building PCRE for various operating systems can be found in the \fBREADME\fP and \fBNON-UNIX-USE\fP files in the source distribution. .P The libraries contains a number of undocumented internal functions and data tables that are used by more than one of the exported external functions, but which are not intended for use by external callers. Their names all begin with "_pcre_" or "_pcre16_", which hopefully will not provoke any name clashes. In some environments, it is possible to control which external symbols are exported when a shared library is built, and in these cases the undocumented symbols are not exported. . . .SH "USER DOCUMENTATION" .rs .sp The user documentation for PCRE comprises a number of different sections. In the "man" format, each of these is a separate "man page". In the HTML format, each is a separate page, linked from the index page. In the plain text format, all the sections, except the \fBpcredemo\fP section, are concatenated, for ease of searching. The sections are as follows: .sp pcre this document pcre16 details of the 16-bit library pcre-config show PCRE installation configuration information pcreapi details of PCRE's native C API pcrebuild options for building PCRE pcrecallout details of the callout feature pcrecompat discussion of Perl compatibility pcrecpp details of the C++ wrapper for the 8-bit library pcredemo a demonstration C program that uses PCRE pcregrep description of the \fBpcregrep\fP command (8-bit only) pcrejit discussion of the just-in-time optimization support pcrelimits details of size and other limits pcrematching discussion of the two matching algorithms pcrepartial details of the partial matching facility .\" JOIN pcrepattern syntax and semantics of supported regular expressions pcreperform discussion of performance issues pcreposix the POSIX-compatible C API for the 8-bit library pcreprecompile details of saving and re-using precompiled patterns pcresample discussion of the pcredemo program pcrestack discussion of stack usage pcresyntax quick syntax reference pcretest description of the \fBpcretest\fP testing command pcreunicode discussion of Unicode and UTF-8/16 support .sp In addition, in the "man" and HTML formats, there is a short page for each 8-bit C library function, listing its arguments and results. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi .P 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 two initials, followed by the two digits 10, at the domain cam.ac.uk. . . .SH REVISION .rs .sp .nf Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_compile.30000644000222100022210000000676011760163326012613 00000000000000.TH PCRE_COMPILE 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B pcre *pcre_compile(const char *\fIpattern\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .PP .B pcre16 *pcre16_compile(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); . .SH DESCRIPTION .rs .sp This function compiles a regular expression into an internal form. It is the same as \fBpcre[16]_compile2()\fP, except for the absence of the \fIerrorcodeptr\fP argument. Its arguments are: .sp \fIpattern\fP A zero-terminated string containing the regular expression to be compiled \fIoptions\fP Zero or more option bits \fIerrptr\fP Where to put an error message \fIerroffset\fP Offset in pattern where error was found \fItableptr\fP Pointer to character tables, or NULL to use the built-in default .sp The option bits are: .sp PCRE_ANCHORED Force pattern anchoring PCRE_AUTO_CALLOUT Compile automatic callouts PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF PCRE_BSR_UNICODE \eR matches all Unicode line endings PCRE_CASELESS Do caseless matching PCRE_DOLLAR_ENDONLY $ not to match newline at end PCRE_DOTALL . matches anything including NL PCRE_DUPNAMES Allow duplicate names for subpatterns PCRE_EXTENDED Ignore white space and # comments PCRE_EXTRA PCRE extra features (not much use currently) PCRE_FIRSTLINE Force matching to be before newline PCRE_JAVASCRIPT_COMPAT JavaScript compatibility PCRE_MULTILINE ^ and $ match newlines within data PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline sequences PCRE_NEWLINE_CR Set CR as the newline sequence PCRE_NEWLINE_CRLF Set CRLF as the newline sequence PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 validity (only relevant if PCRE_UTF16 is set) PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) PCRE_UCP Use Unicode properties for \ed, \ew, etc. PCRE_UNGREEDY Invert greediness of quantifiers PCRE_UTF16 Run in \fBpcre16_compile()\fP UTF-16 mode PCRE_UTF8 Run in \fBpcre_compile()\fP UTF-8 mode .sp PCRE must be built with UTF support in order to use PCRE_UTF8/16 and PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used. .P The yield of the function is a pointer to a private data structure that contains the compiled pattern, or NULL if an error was detected. Note that compiling regular expressions with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre16.30000644000222100022210000003150711762370425011251 00000000000000.TH PCRE 3 "14 April 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions .sp .B #include . . .SH "PCRE 16-BIT API BASIC FUNCTIONS" .rs .sp .SM .B pcre16 *pcre16_compile(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .PP .B pcre16 *pcre16_compile2(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, .ti +5n .B int *\fIerrorcodeptr\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .PP .B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP); .PP .B void pcre16_free_study(pcre16_extra *\fIextra\fP); .PP .B int pcre16_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," .ti +5n .B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); .PP .B int pcre16_dfa_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," .ti +5n .B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, .ti +5n .B int *\fIworkspace\fP, int \fIwscount\fP); . . .SH "PCRE 16-BIT API STRING EXTRACTION FUNCTIONS" .rs .sp .B int pcre16_copy_named_substring(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, .ti +5n .B PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP); .PP .B int pcre16_copy_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP, .ti +5n .B int \fIbuffersize\fP); .PP .B int pcre16_get_named_substring(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, .ti +5n .B PCRE_SPTR16 *\fIstringptr\fP); .PP .B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIname\fP); .PP .B int pcre16_get_stringtable_entries(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP); .PP .B int pcre16_get_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, int \fIstringnumber\fP, .ti +5n .B PCRE_SPTR16 *\fIstringptr\fP); .PP .B int pcre16_get_substring_list(PCRE_SPTR16 \fIsubject\fP, .ti +5n .B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR16 **\fIlistptr\fP);" .PP .B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP); .PP .B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP); . . .SH "PCRE 16-BIT API AUXILIARY FUNCTIONS" .rs .sp .B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); .PP .B void pcre16_jit_stack_free(pcre16_jit_stack *\fIstack\fP); .PP .B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP, .ti +5n .B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP); .PP .B const unsigned char *pcre16_maketables(void); .PP .B int pcre16_fullinfo(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," .ti +5n .B int \fIwhat\fP, void *\fIwhere\fP); .PP .B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP); .PP .B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP); .PP .B const char *pcre16_version(void); .PP .B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP, .ti +5n .B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP); . . .SH "PCRE 16-BIT API INDIRECTED FUNCTIONS" .rs .sp .B void *(*pcre16_malloc)(size_t); .PP .B void (*pcre16_free)(void *); .PP .B void *(*pcre16_stack_malloc)(size_t); .PP .B void (*pcre16_stack_free)(void *); .PP .B int (*pcre16_callout)(pcre16_callout_block *); . . .SH "PCRE 16-BIT API 16-BIT-ONLY FUNCTION" .rs .sp .B int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *\fIoutput\fP, .ti +5n .B PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIbyte_order\fP, .ti +5n .B int \fIkeep_boms\fP); . . .SH "THE PCRE 16-BIT LIBRARY" .rs .sp Starting with release 8.30, it is possible to compile a PCRE library that supports 16-bit character strings, including UTF-16 strings, as well as or instead of the original 8-bit library. The majority of the work to make this possible was done by Zoltan Herczeg. The two libraries contain identical sets of functions, used in exactly the same way. Only the names of the functions and the data types of their arguments and results are different. To avoid over-complication and reduce the documentation maintenance load, most of the PCRE documentation describes the 8-bit library, with only occasional references to the 16-bit library. This page describes what is different when you use the 16-bit library. .P WARNING: A single application can be linked with both libraries, but you must take care when processing any particular pattern to use functions from just one library. For example, if you want to study a pattern that was compiled with \fBpcre16_compile()\fP, you must do so with \fBpcre16_study()\fP, not \fBpcre_study()\fP, and you must free the study data with \fBpcre16_free_study()\fP. . . .SH "THE HEADER FILE" .rs .sp There is only one header file, \fBpcre.h\fP. It contains prototypes for all the functions in both libraries, as well as definitions of flags, structures, error codes, etc. . . .SH "THE LIBRARY NAME" .rs .sp In Unix-like systems, the 16-bit library is called \fBlibpcre16\fP, and can normally be accesss by adding \fB-lpcre16\fP to the command for linking an application that uses PCRE. . . .SH "STRING TYPES" .rs .sp In the 8-bit library, strings are passed to PCRE library functions as vectors of bytes with the C type "char *". In the 16-bit library, strings are passed as vectors of unsigned 16-bit quantities. The macro PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is defined as "const PCRE_UCHAR16 *". In very many environments, "short int" is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16 as "short int", but checks that it really is a 16-bit data type. If it is not, the build fails with an error message telling the maintainer to modify the definition appropriately. . . .SH "STRUCTURE TYPES" .rs .sp The types of the opaque structures that are used for compiled 16-bit patterns and JIT stacks are \fBpcre16\fP and \fBpcre16_jit_stack\fP respectively. The type of the user-accessible structure that is returned by \fBpcre16_study()\fP is \fBpcre16_extra\fP, and the type of the structure that is used for passing data to a callout function is \fBpcre16_callout_block\fP. These structures contain the same fields, with the same names, as their 8-bit counterparts. The only difference is that pointers to character strings are 16-bit instead of 8-bit types. . . .SH "16-BIT FUNCTIONS" .rs .sp For every function in the 8-bit library there is a corresponding function in the 16-bit library with a name that starts with \fBpcre16_\fP instead of \fBpcre_\fP. The prototypes are listed above. In addition, there is one extra function, \fBpcre16_utf16_to_host_byte_order()\fP. This is a utility function that converts a UTF-16 character string to host byte order if necessary. The other 16-bit functions expect the strings they are passed to be in host byte order. .P The \fIinput\fP and \fIoutput\fP arguments of \fBpcre16_utf16_to_host_byte_order()\fP may point to the same address, that is, conversion in place is supported. The output buffer must be at least as long as the input. .P The \fIlength\fP argument specifies the number of 16-bit data units in the input string; a negative value specifies a zero-terminated string. .P If \fIbyte_order\fP is NULL, it is assumed that the string starts off in host byte order. This may be changed by byte-order marks (BOMs) anywhere in the string (commonly as the first character). .P If \fIbyte_order\fP is not NULL, a non-zero value of the integer to which it points means that the input starts off in host byte order, otherwise the opposite order is assumed. Again, BOMs in the string can change this. The final byte order is passed back at the end of processing. .P If \fIkeep_boms\fP is not zero, byte-order mark characters (0xfeff) are copied into the output string. Otherwise they are discarded. .P The result of the function is the number of 16-bit units placed into the output buffer, including the zero terminator if the string was zero-terminated. . . .SH "SUBJECT STRING OFFSETS" .rs .sp The offsets within subject strings that are returned by the matching functions are in 16-bit units rather than bytes. . . .SH "NAMED SUBPATTERNS" .rs .sp The name-to-number translation table that is maintained for named subpatterns uses 16-bit characters. The \fBpcre16_get_stringtable_entries()\fP function returns the length of each entry in the table as the number of 16-bit data units. . . .SH "OPTION NAMES" .rs .sp There are two new general option names, PCRE_UTF16 and PCRE_NO_UTF16_CHECK, which correspond to PCRE_UTF8 and PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options define the same bits in the options word. There is a discussion about the .\" HTML .\" validity of UTF-16 strings .\" in the .\" HREF \fBpcreunicode\fP .\" page. .P For the \fBpcre16_config()\fP function there is an option PCRE_CONFIG_UTF16 that returns 1 if UTF-16 support is configured, otherwise 0. If this option is given to \fBpcre_config()\fP, or if the PCRE_CONFIG_UTF8 option is given to \fBpcre16_config()\fP, the result is the PCRE_ERROR_BADOPTION error. . . .SH "CHARACTER CODES" .rs .sp In 16-bit mode, when PCRE_UTF16 is not set, character values are treated in the same way as in 8-bit, non UTF-8 mode, except, of course, that they can range from 0 to 0xffff instead of 0 to 0xff. Character types for characters less than 0xff can therefore be influenced by the locale in the same way as before. Characters greater than 0xff have only one case, and no "type" (such as letter or digit). .P In UTF-16 mode, the character code is Unicode, in the range 0 to 0x10ffff, with the exception of values in the range 0xd800 to 0xdfff because those are "surrogate" values that are used in pairs to encode values greater than 0xffff. .P A UTF-16 string can indicate its endianness by special code knows as a byte-order mark (BOM). The PCRE functions do not handle this, expecting strings to be in host byte order. A utility function called \fBpcre16_utf16_to_host_byte_order()\fP is provided to help with this (see above). . . .SH "ERROR NAMES" .rs .sp The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 correspond to their 8-bit counterparts. The error PCRE_ERROR_BADMODE is given when a compiled pattern is passed to a function that processes patterns in the other mode, for example, if a pattern compiled with \fBpcre_compile()\fP is passed to \fBpcre16_exec()\fP. .P There are new error codes whose names begin with PCRE_UTF16_ERR for invalid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for UTF-8 strings that are described in the section entitled .\" HTML .\" "Reason codes for invalid UTF-8 strings" .\" in the main .\" HREF \fBpcreapi\fP .\" page. The UTF-16 errors are: .sp PCRE_UTF16_ERR1 Missing low surrogate at end of string PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate PCRE_UTF16_ERR3 Isolated low surrogate PCRE_UTF16_ERR4 Invalid character 0xfffe . . .SH "ERROR TEXTS" .rs .sp If there is an error while compiling a pattern, the error text that is passed back by \fBpcre16_compile()\fP or \fBpcre16_compile2()\fP is still an 8-bit character string, zero-terminated. . . .SH "CALLOUTS" .rs .sp The \fIsubject\fP and \fImark\fP fields in the callout block that is passed to a callout function point to 16-bit vectors. . . .SH "TESTING" .rs .sp The \fBpcretest\fP program continues to operate with 8-bit input and output files, but it can be used for testing the 16-bit library. If it is run with the command line option \fB-16\fP, patterns and subject strings are converted from 8-bit to 16-bit before being passed to PCRE, and the 16-bit library functions are used instead of the 8-bit ones. Returned 16-bit strings are converted to 8-bit for output. If the 8-bit library was not compiled, \fBpcretest\fP defaults to 16-bit and the \fB-16\fP option is ignored. .P When PCRE is being built, the \fBRunTest\fP script that is called by "make check" uses the \fBpcretest\fP \fB-C\fP option to discover which of the 8-bit and 16-bit libraries has been built, and runs the tests appropriately. . . .SH "NOT SUPPORTED IN 16-BIT MODE" .rs .sp Not all the features of the 8-bit library are available with the 16-bit library. The C++ and POSIX wrapper functions support only the 8-bit library, and the \fBpcregrep\fP program is at present 8-bit only. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 14 April 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre.txt0000644000222100022210000154104711775533020011561 00000000000000----------------------------------------------------------------------------- This file contains a concatenation of the PCRE man pages, converted to plain text format for ease of searching with a text editor, or for use on systems that do not have a man page processor. The small individual files that give synopses of each function in the library have not been included. Neither has the pcredemo program. There are separate text files for the pcregrep and pcretest commands. ----------------------------------------------------------------------------- PCRE(3) PCRE(3) NAME PCRE - Perl-compatible regular expressions INTRODUCTION The PCRE library is a set of functions that implement regular expres- sion pattern matching using the same syntax and semantics as Perl, with just a few differences. Some features that appeared in Python and PCRE before they appeared in Perl are also available using the Python syn- tax, there is some support for one or two .NET and Oniguruma syntax items, and there is an option for requesting some minor changes that give better JavaScript compatibility. Starting with release 8.30, it is possible to compile two separate PCRE libraries: the original, which supports 8-bit character strings (including UTF-8 strings), and a second library that supports 16-bit character strings (including UTF-16 strings). The build process allows either one or both to be built. The majority of the work to make this possible was done by Zoltan Herczeg. The two libraries contain identical sets of functions, except that the names in the 16-bit library start with pcre16_ instead of pcre_. To avoid over-complication and reduce the documentation maintenance load, most of the documentation describes the 8-bit library, with the differ- ences for the 16-bit library described separately in the pcre16 page. References to functions or structures of the form pcre[16]_xxx should be read as meaning "pcre_xxx when using the 8-bit library and pcre16_xxx when using the 16-bit library". The current implementation of PCRE corresponds approximately with Perl 5.12, including support for UTF-8/16 encoded strings and Unicode gen- eral category properties. However, UTF-8/16 and Unicode support has to be explicitly enabled; it is not the default. The Unicode tables corre- spond to Unicode release 6.0.0. In addition to the Perl-compatible matching function, PCRE contains an alternative function that matches the same compiled patterns in a dif- ferent way. In certain circumstances, the alternative function has some advantages. For a discussion of the two matching algorithms, see the pcrematching page. PCRE is written in C and released as a C library. A number of people have written wrappers and interfaces of various kinds. In particular, Google Inc. have provided a comprehensive C++ wrapper for the 8-bit library. This is now included as part of the PCRE distribution. The pcrecpp page has details of this interface. Other people's contribu- tions can be found in the Contrib directory at the primary FTP site, which is: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre Details of exactly which Perl regular expression features are and are not supported by PCRE are given in separate documents. See the pcrepat- tern and pcrecompat pages. There is a syntax summary in the pcresyntax page. Some features of PCRE can be included, excluded, or changed when the library is built. The pcre_config() function makes it possible for a client to discover which features are available. The features them- selves are described in the pcrebuild page. Documentation about build- ing PCRE for various operating systems can be found in the README and NON-UNIX-USE files in the source distribution. The libraries contains a number of undocumented internal functions and data tables that are used by more than one of the exported external functions, but which are not intended for use by external callers. Their names all begin with "_pcre_" or "_pcre16_", which hopefully will not provoke any name clashes. In some environments, it is possible to control which external symbols are exported when a shared library is built, and in these cases the undocumented symbols are not exported. USER DOCUMENTATION The user documentation for PCRE comprises a number of different sec- tions. In the "man" format, each of these is a separate "man page". In the HTML format, each is a separate page, linked from the index page. In the plain text format, all the sections, except the pcredemo sec- tion, are concatenated, for ease of searching. The sections are as fol- lows: pcre this document pcre16 details of the 16-bit library pcre-config show PCRE installation configuration information pcreapi details of PCRE's native C API pcrebuild options for building PCRE pcrecallout details of the callout feature pcrecompat discussion of Perl compatibility pcrecpp details of the C++ wrapper for the 8-bit library pcredemo a demonstration C program that uses PCRE pcregrep description of the pcregrep command (8-bit only) pcrejit discussion of the just-in-time optimization support pcrelimits details of size and other limits pcrematching discussion of the two matching algorithms pcrepartial details of the partial matching facility pcrepattern syntax and semantics of supported regular expressions pcreperform discussion of performance issues pcreposix the POSIX-compatible C API for the 8-bit library pcreprecompile details of saving and re-using precompiled patterns pcresample discussion of the pcredemo program pcrestack discussion of stack usage pcresyntax quick syntax reference pcretest description of the pcretest testing command pcreunicode discussion of Unicode and UTF-8/16 support In addition, in the "man" and HTML formats, there is a short page for each 8-bit C library function, listing its arguments and results. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. 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 two initials, followed by the two digits 10, at the domain cam.ac.uk. REVISION Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCRE(3) PCRE(3) NAME PCRE - Perl-compatible regular expressions #include PCRE 16-BIT API BASIC FUNCTIONS pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr); pcre16_extra *pcre16_study(const pcre16 *code, int options, const char **errptr); void pcre16_free_study(pcre16_extra *extra); int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, PCRE_SPTR16 subject, int length, int startoffset, int options, int *ovector, int ovecsize); int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, PCRE_SPTR16 subject, int length, int startoffset, int options, int *ovector, int ovecsize, int *workspace, int wscount); PCRE 16-BIT API STRING EXTRACTION FUNCTIONS int pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_UCHAR16 *buffer, int buffersize); int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, int buffersize); int pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_SPTR16 *stringptr); int pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 name); int pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last); int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_SPTR16 *stringptr); int pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 **listptr); void pcre16_free_substring(PCRE_SPTR16 stringptr); void pcre16_free_substring_list(PCRE_SPTR16 *stringptr); PCRE 16-BIT API AUXILIARY FUNCTIONS pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize); void pcre16_jit_stack_free(pcre16_jit_stack *stack); void pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *data); const unsigned char *pcre16_maketables(void); int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, int what, void *where); int pcre16_refcount(pcre16 *code, int adjust); int pcre16_config(int what, void *where); const char *pcre16_version(void); int pcre16_pattern_to_host_byte_order(pcre16 *code, pcre16_extra *extra, const unsigned char *tables); PCRE 16-BIT API INDIRECTED FUNCTIONS void *(*pcre16_malloc)(size_t); void (*pcre16_free)(void *); void *(*pcre16_stack_malloc)(size_t); void (*pcre16_stack_free)(void *); int (*pcre16_callout)(pcre16_callout_block *); PCRE 16-BIT API 16-BIT-ONLY FUNCTION int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input, int length, int *byte_order, int keep_boms); THE PCRE 16-BIT LIBRARY Starting with release 8.30, it is possible to compile a PCRE library that supports 16-bit character strings, including UTF-16 strings, as well as or instead of the original 8-bit library. The majority of the work to make this possible was done by Zoltan Herczeg. The two libraries contain identical sets of functions, used in exactly the same way. Only the names of the functions and the data types of their argu- ments and results are different. To avoid over-complication and reduce the documentation maintenance load, most of the PCRE documentation describes the 8-bit library, with only occasional references to the 16-bit library. This page describes what is different when you use the 16-bit library. WARNING: A single application can be linked with both libraries, but you must take care when processing any particular pattern to use func- tions from just one library. For example, if you want to study a pat- tern that was compiled with pcre16_compile(), you must do so with pcre16_study(), not pcre_study(), and you must free the study data with pcre16_free_study(). THE HEADER FILE There is only one header file, pcre.h. It contains prototypes for all the functions in both libraries, as well as definitions of flags, structures, error codes, etc. THE LIBRARY NAME In Unix-like systems, the 16-bit library is called libpcre16, and can normally be accesss by adding -lpcre16 to the command for linking an application that uses PCRE. STRING TYPES In the 8-bit library, strings are passed to PCRE library functions as vectors of bytes with the C type "char *". In the 16-bit library, strings are passed as vectors of unsigned 16-bit quantities. The macro PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is defined as "const PCRE_UCHAR16 *". In very many environments, "short int" is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16 as "short int", but checks that it really is a 16-bit data type. If it is not, the build fails with an error message telling the maintainer to modify the definition appropriately. STRUCTURE TYPES The types of the opaque structures that are used for compiled 16-bit patterns and JIT stacks are pcre16 and pcre16_jit_stack respectively. The type of the user-accessible structure that is returned by pcre16_study() is pcre16_extra, and the type of the structure that is used for passing data to a callout function is pcre16_callout_block. These structures contain the same fields, with the same names, as their 8-bit counterparts. The only difference is that pointers to character strings are 16-bit instead of 8-bit types. 16-BIT FUNCTIONS For every function in the 8-bit library there is a corresponding func- tion in the 16-bit library with a name that starts with pcre16_ instead of pcre_. The prototypes are listed above. In addition, there is one extra function, pcre16_utf16_to_host_byte_order(). This is a utility function that converts a UTF-16 character string to host byte order if necessary. The other 16-bit functions expect the strings they are passed to be in host byte order. The input and output arguments of pcre16_utf16_to_host_byte_order() may point to the same address, that is, conversion in place is supported. The output buffer must be at least as long as the input. The length argument specifies the number of 16-bit data units in the input string; a negative value specifies a zero-terminated string. If byte_order is NULL, it is assumed that the string starts off in host byte order. This may be changed by byte-order marks (BOMs) anywhere in the string (commonly as the first character). If byte_order is not NULL, a non-zero value of the integer to which it points means that the input starts off in host byte order, otherwise the opposite order is assumed. Again, BOMs in the string can change this. The final byte order is passed back at the end of processing. If keep_boms is not zero, byte-order mark characters (0xfeff) are copied into the output string. Otherwise they are discarded. The result of the function is the number of 16-bit units placed into the output buffer, including the zero terminator if the string was zero-terminated. SUBJECT STRING OFFSETS The offsets within subject strings that are returned by the matching functions are in 16-bit units rather than bytes. NAMED SUBPATTERNS The name-to-number translation table that is maintained for named sub- patterns uses 16-bit characters. The pcre16_get_stringtable_entries() function returns the length of each entry in the table as the number of 16-bit data units. OPTION NAMES There are two new general option names, PCRE_UTF16 and PCRE_NO_UTF16_CHECK, which correspond to PCRE_UTF8 and PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options define the same bits in the options word. There is a discussion about the validity of UTF-16 strings in the pcreunicode page. For the pcre16_config() function there is an option PCRE_CONFIG_UTF16 that returns 1 if UTF-16 support is configured, otherwise 0. If this option is given to pcre_config(), or if the PCRE_CONFIG_UTF8 option is given to pcre16_config(), the result is the PCRE_ERROR_BADOPTION error. CHARACTER CODES In 16-bit mode, when PCRE_UTF16 is not set, character values are treated in the same way as in 8-bit, non UTF-8 mode, except, of course, that they can range from 0 to 0xffff instead of 0 to 0xff. Character types for characters less than 0xff can therefore be influenced by the locale in the same way as before. Characters greater than 0xff have only one case, and no "type" (such as letter or digit). In UTF-16 mode, the character code is Unicode, in the range 0 to 0x10ffff, with the exception of values in the range 0xd800 to 0xdfff because those are "surrogate" values that are used in pairs to encode values greater than 0xffff. A UTF-16 string can indicate its endianness by special code knows as a byte-order mark (BOM). The PCRE functions do not handle this, expecting strings to be in host byte order. A utility function called pcre16_utf16_to_host_byte_order() is provided to help with this (see above). ERROR NAMES The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 corre- spond to their 8-bit counterparts. The error PCRE_ERROR_BADMODE is given when a compiled pattern is passed to a function that processes patterns in the other mode, for example, if a pattern compiled with pcre_compile() is passed to pcre16_exec(). There are new error codes whose names begin with PCRE_UTF16_ERR for invalid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for UTF-8 strings that are described in the section entitled "Reason codes for invalid UTF-8 strings" in the main pcreapi page. The UTF-16 errors are: PCRE_UTF16_ERR1 Missing low surrogate at end of string PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate PCRE_UTF16_ERR3 Isolated low surrogate PCRE_UTF16_ERR4 Invalid character 0xfffe ERROR TEXTS If there is an error while compiling a pattern, the error text that is passed back by pcre16_compile() or pcre16_compile2() is still an 8-bit character string, zero-terminated. CALLOUTS The subject and mark fields in the callout block that is passed to a callout function point to 16-bit vectors. TESTING The pcretest program continues to operate with 8-bit input and output files, but it can be used for testing the 16-bit library. If it is run with the command line option -16, patterns and subject strings are con- verted from 8-bit to 16-bit before being passed to PCRE, and the 16-bit library functions are used instead of the 8-bit ones. Returned 16-bit strings are converted to 8-bit for output. If the 8-bit library was not compiled, pcretest defaults to 16-bit and the -16 option is ignored. When PCRE is being built, the RunTest script that is called by "make check" uses the pcretest -C option to discover which of the 8-bit and 16-bit libraries has been built, and runs the tests appropriately. NOT SUPPORTED IN 16-BIT MODE Not all the features of the 8-bit library are available with the 16-bit library. The C++ and POSIX wrapper functions support only the 8-bit library, and the pcregrep program is at present 8-bit only. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 14 April 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREBUILD(3) PCREBUILD(3) NAME PCRE - Perl-compatible regular expressions PCRE BUILD-TIME OPTIONS This document describes the optional features of PCRE that can be selected when the library is compiled. It assumes use of the configure script, where the optional features are selected or deselected by pro- viding options to configure before running the make command. However, the same options can be selected in both Unix-like and non-Unix-like environments using the GUI facility of cmake-gui if you are using CMake instead of configure to build PCRE. There is a lot more information about building PCRE in non-Unix-like environments in the file called NON_UNIX_USE, which is part of the PCRE distribution. You should consult this file as well as the README file if you are building in a non-Unix-like environment. The complete list of options for configure (which includes the standard ones such as the selection of the installation directory) can be obtained by running ./configure --help The following sections include descriptions of options whose names begin with --enable or --disable. These settings specify changes to the defaults for the configure command. Because of the way that configure works, --enable and --disable always come in pairs, so the complemen- tary option always exists as well, but as it specifies the default, it is not described. BUILDING 8-BIT and 16-BIT LIBRARIES By default, a library called libpcre is built, containing functions that take string arguments contained in vectors of bytes, either as single-byte characters, or interpreted as UTF-8 strings. You can also build a separate library, called libpcre16, in which strings are con- tained in vectors of 16-bit data units and interpreted either as sin- gle-unit characters or UTF-16 strings, by adding --enable-pcre16 to the configure command. If you do not want the 8-bit library, add --disable-pcre8 as well. At least one of the two libraries must be built. Note that the C++ and POSIX wrappers are for the 8-bit library only, and that pcre- grep is an 8-bit program. None of these are built if you select only the 16-bit library. BUILDING SHARED AND STATIC LIBRARIES The PCRE building process uses libtool to build both shared and static Unix libraries by default. You can suppress one of these by adding one of --disable-shared --disable-static to the configure command, as required. C++ SUPPORT By default, if the 8-bit library is being built, the configure script will search for a C++ compiler and C++ header files. If it finds them, it automatically builds the C++ wrapper library (which supports only 8-bit strings). You can disable this by adding --disable-cpp to the configure command. UTF-8 and UTF-16 SUPPORT To build PCRE with support for UTF Unicode character strings, add --enable-utf to the configure command. This setting applies to both libraries, adding support for UTF-8 to the 8-bit library and support for UTF-16 to the 16-bit library. There are no separate options for enabling UTF-8 and UTF-16 independently because that would allow ridiculous settings such as requesting UTF-16 support while building only the 8-bit library. It is not possible to build one library with UTF support and the other without in the same configuration. (For backwards compatibil- ity, --enable-utf8 is a synonym of --enable-utf.) Of itself, this setting does not make PCRE treat strings as UTF-8 or UTF-16. As well as compiling PCRE with this option, you also have have to set the PCRE_UTF8 or PCRE_UTF16 option when you call one of the pat- tern compiling functions. If you set --enable-utf when compiling in an EBCDIC environment, PCRE expects its input to be either ASCII or UTF-8 (depending on the run- time option). It is not possible to support both EBCDIC and UTF-8 codes in the same version of the library. Consequently, --enable-utf and --enable-ebcdic are mutually exclusive. UNICODE CHARACTER PROPERTY SUPPORT UTF support allows the libraries to process character codepoints up to 0x10ffff in the strings that they handle. On its own, however, it does not provide any facilities for accessing the properties of such charac- ters. If you want to be able to use the pattern escapes \P, \p, and \X, which refer to Unicode character properties, you must add --enable-unicode-properties to the configure command. This implies UTF support, even if you have not explicitly requested it. Including Unicode property support adds around 30K of tables to the PCRE library. Only the general category properties such as Lu and Nd are supported. Details are given in the pcrepattern documentation. JUST-IN-TIME COMPILER SUPPORT Just-in-time compiler support is included in the build by specifying --enable-jit This support is available only for certain hardware architectures. If this option is set for an unsupported architecture, a compile time error occurs. See the pcrejit documentation for a discussion of JIT usage. When JIT support is enabled, pcregrep automatically makes use of it, unless you add --disable-pcregrep-jit to the "configure" command. CODE VALUE OF NEWLINE By default, PCRE interprets the linefeed (LF) character as indicating the end of a line. This is the normal newline character on Unix-like systems. You can compile PCRE to use carriage return (CR) instead, by adding --enable-newline-is-cr 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. There is a fourth option, specified by --enable-newline-is-anycrlf which causes PCRE to recognize any of the three sequences CR, LF, or CRLF as indicating a line ending. Finally, a fifth option, specified by --enable-newline-is-any causes PCRE to recognize any Unicode newline sequence. 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. WHAT \R MATCHES By default, the sequence \R in a pattern matches any Unicode newline sequence, whatever has been selected as the line ending sequence. If you specify --enable-bsr-anycrlf the default is changed so that \R matches only CR, LF, or CRLF. What- ever is selected when PCRE is built can be overridden when the library functions are called. POSIX MALLOC USAGE When the 8-bit library is called through the POSIX interface (see the pcreposix documentation), additional working storage is required for holding the pointers to capturing substrings, because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper func- tion uses space on the stack, because this is faster than using mal- loc() for each call. The default threshold above which the stack is no longer used is 10; it can be changed by adding a setting such as --with-posix-malloc-threshold=20 to the configure command. HANDLING VERY LARGE PATTERNS Within a compiled pattern, offset values are used to point from one part to another (for example, from an opening parenthesis to an alter- nation metacharacter). By default, two-byte values are used for these offsets, leading to a maximum size for a compiled pattern of around 64K. This is sufficient to handle all but the most gigantic patterns. Nevertheless, some people do want to process truly enormous patterns, so it is possible to compile PCRE to use three-byte or four-byte off- sets by adding a setting such as --with-link-size=3 to the configure command. The value given must be 2, 3, or 4. For the 16-bit library, a value of 3 is rounded up to 4. Using longer offsets slows down the operation of PCRE because it has to load additional data when handling them. AVOIDING EXCESSIVE STACK USAGE When matching with the pcre_exec() function, PCRE implements backtrack- 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, 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 to the configure command. With this configuration, PCRE will use the pcre_stack_malloc and pcre_stack_free variables to call memory manage- ment functions. By default these point to malloc() and free(), but you can replace the pointers so that your own functions are used instead. Separate functions are provided rather than using pcre_malloc and pcre_free because the usage is very predictable: the block sizes requested are always the same, and the blocks are always freed in reverse order. A calling program might be able to implement optimized functions that perform better than malloc() and free(). PCRE runs noticeably more slowly when built in this way. This option affects only the pcre_exec() function; it is not relevant for pcre_dfa_exec(). 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. CREATING CHARACTER TABLES AT BUILD TIME PCRE uses fixed tables for processing characters whose code values are less than 256. By default, PCRE is built with a set of tables that are distributed in the file pcre_chartables.c.dist. These tables are for ASCII codes only. If you add --enable-rebuild-chartables to the configure command, the distributed tables are no longer used. Instead, a program called dftables is compiled and run. This outputs the source for new set of tables, created in the default locale of your C run-time system. (This method of replacing the tables does not work if you are cross compiling, because dftables is run on the local host. If you need to create alternative tables when cross compiling, you will have to do so "by hand".) 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). This is the case for most computer operating systems. PCRE can, how- ever, be compiled to run in an EBCDIC environment by adding --enable-ebcdic to the configure command. This setting implies --enable-rebuild-charta- bles. You should only use it if you know that you are in an EBCDIC environment (for example, an IBM mainframe operating system). The --enable-ebcdic option is incompatible with --enable-utf. PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT By default, pcregrep reads all files as plain text. You can build it so that it recognizes files whose names end in .gz or .bz2, and reads them with libz or libbz2, respectively, by adding one or both of --enable-pcregrep-libz --enable-pcregrep-libbz2 to the configure command. These options naturally require that the rel- evant libraries are installed on your system. Configuration will fail if they are not. PCREGREP BUFFER SIZE pcregrep uses an internal buffer to hold a "window" on the file it is scanning, in order to be able to output "before" and "after" lines when it finds a match. The size of the buffer is controlled by a parameter whose default value is 20K. The buffer itself is three times this size, but because of the way it is used for holding "before" lines, the long- est line that is guaranteed to be processable is the parameter size. You can change the default parameter value by adding, for example, --with-pcregrep-bufsize=50K to the configure command. The caller of pcregrep can, however, override this value by specifying a run-time option. PCRETEST OPTION FOR LIBREADLINE SUPPORT If you add --enable-pcretest-libreadline to the configure command, pcretest is linked with the libreadline library, and when its input is from a terminal, it reads it using the readline() function. This provides line-editing and history facilities. Note that libreadline is GPL-licensed, so if you distribute a binary of pcretest linked in this way, there may be licensing issues. Setting this option causes the -lreadline option to be added to the pcretest build. In many operating environments with a sytem-installed libreadline this is sufficient. However, in some environments (e.g. if an unmodified distribution version of readline is in use), some extra configuration may be necessary. The INSTALL file for libreadline says this: "Readline uses the termcap functions, but does not link with the termcap or curses library itself, allowing applications which link with readline the to choose an appropriate library." If your environment has not been set up so that an appropriate library is automatically included, you may need to add something like LIBS="-ncurses" immediately before the configure command. SEE ALSO pcreapi(3), pcre16, pcre_config(3). AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 07 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREMATCHING(3) PCREMATCHING(3) NAME PCRE - Perl-compatible regular expressions PCRE MATCHING ALGORITHMS This document describes the two different algorithms that are available in PCRE for matching a compiled regular expression against a given sub- ject string. The "standard" algorithm is the one provided by the pcre_exec() and pcre16_exec() functions. These work in the same was as Perl's matching function, and provide a Perl-compatible matching opera- tion. The just-in-time (JIT) optimization that is described in the pcrejit documentation is compatible with these functions. An alternative algorithm is provided by the pcre_dfa_exec() and pcre16_dfa_exec() functions; they operate in a different way, and are not Perl-compatible. This alternative has advantages and disadvantages compared with the standard algorithm, and these are described below. When there is only one possible way in which a given subject string can match a pattern, the two algorithms give the same answer. A difference arises, however, when there are multiple possibilities. For example, if the pattern ^<.*> is matched against the string there are three possible answers. The standard algorithm finds only one of them, whereas the alternative algorithm finds all three. REGULAR EXPRESSIONS AS TREES The set of strings that are matched by a regular expression can be rep- 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 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 In the terminology of Jeffrey Friedl's book "Mastering Regular Expres- sions", the standard algorithm is an "NFA algorithm". It conducts a depth-first search of the pattern tree. That is, it proceeds along a single path through the tree, checking that the subject matches what is required. When there is a mismatch, the algorithm tries any alterna- tives at the current point, and if they all fail, it backs up to the previous branch point in the tree, and tries the next alternative branch at that level. This often involves backing up (moving to the left) in the subject string as well. The order in which repetition branches are tried is controlled by the greedy or ungreedy nature of the quantifier. If a leaf node is reached, a matching string has been found, and at that point the algorithm stops. Thus, if there is more than one possi- ble match, this algorithm returns the first one that it finds. Whether this is the shortest, the longest, or some intermediate length depends on the way the greedy and ungreedy repetition quantifiers are specified in the pattern. Because it ends up with a single path through the tree, it is rela- tively straightforward for this algorithm to keep track of the sub- strings that are matched by portions of the pattern in parentheses. This provides support for capturing parentheses and back references. THE ALTERNATIVE MATCHING ALGORITHM This algorithm conducts a breadth-first search of the tree. Starting from the first matching point in the subject, it scans the subject string from left to right, once, character by character, and as it does this, it remembers all the paths through the tree that represent valid matches. In Friedl's terminology, this is a kind of "DFA algorithm", though it is not implemented as a traditional finite state machine (it keeps multiple states active simultaneously). Although the general principle of this matching algorithm is that it scans the subject string only once, without backtracking, there is one exception: when a lookaround assertion is encountered, the characters following or preceding the current point have to be independently inspected. The scan continues until either the end of the subject is reached, or there are no more unterminated paths. At this point, terminated paths represent the different matching possibilities (if there are none, the match has failed). Thus, if there is more than one possible match, this algorithm finds all of them, and in particular, it finds the long- est. The matches are returned in decreasing order of length. There is an option to stop the algorithm after the first match (which is neces- sarily the shortest) is found. Note that all the matches that are found start at the same point in the subject. If the pattern cat(er(pillar)?)? is matched against the string "the caterpillar catchment", the result will be the three strings "caterpillar", "cater", and "cat" that start at the fifth character of the subject. The algorithm does not automati- cally move on to find matches that start at later positions. There are a number of features of PCRE regular expressions that are not supported by the alternative matching algorithm. They are as follows: 1. Because the algorithm finds all possible matches, the greedy or ungreedy nature of repetition quantifiers is not relevant. Greedy and ungreedy quantifiers are treated in exactly the same way. However, pos- sessive quantifiers can make a difference when what follows could also match what is quantified, for example in a pattern like this: ^a++\w! This pattern matches "aaab!" but not "aaa!", which would be matched by a non-possessive quantifier. Similarly, if an atomic group is present, it is matched as if it were a standalone pattern at the current point, and the longest match is then "locked in" for the rest of the overall pattern. 2. When dealing with multiple paths through the tree simultaneously, it is not straightforward to keep track of captured substrings for the different matching possibilities, and PCRE's implementation of this algorithm does not attempt to do this. This means that no captured sub- strings are available. 3. Because no substrings are captured, back references within the pat- tern are not supported, and cause errors if encountered. 4. For the same reason, conditional expressions that use a backrefer- ence as the condition or test for a specific group recursion are not supported. 5. Because many paths through the tree may be active, the \K escape sequence, which resets the start of the match when encountered (but may be on some paths and not on others), is not supported. It causes an error if encountered. 6. Callouts are supported, but the value of the capture_top field is always 1, and the value of the capture_last field is always -1. 7. The \C escape sequence, which (in the standard algorithm) always matches a single data unit, even in UTF-8 or UTF-16 modes, is not sup- ported in these modes, because the alternative algorithm moves through the subject string one character (not data unit) at a time, for all active paths through the tree. 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) are not supported. (*FAIL) is supported, and behaves like a failing negative assertion. ADVANTAGES OF THE ALTERNATIVE ALGORITHM Using the alternative matching algorithm provides the following advan- tages: 1. All possible matches (at a single point in the subject) are automat- ically found, and in particular, the longest match is found. To find more than one match using the standard algorithm, you have to do kludgy things with callouts. 2. Because the alternative algorithm scans the subject string just once, and never needs to backtrack (except for lookbehinds), it is pos- sible to pass very long subject strings to the matching function in several pieces, checking for partial matching each time. Although it is possible to do multi-segment matching using the standard algorithm by retaining partially matched substrings, it is more complicated. The pcrepartial documentation gives details of partial matching and dis- cusses multi-segment matching. DISADVANTAGES OF THE ALTERNATIVE ALGORITHM The alternative algorithm suffers from a number of disadvantages: 1. It is substantially slower than the standard algorithm. This is partly because it has to search for all possible matches, but is also because it is less susceptible to optimization. 2. Capturing parentheses and back references are not supported. 3. Although atomic groups are supported, their use does not provide the performance advantage that it does for the standard algorithm. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 08 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREAPI(3) PCREAPI(3) NAME PCRE - Perl-compatible regular expressions #include PCRE NATIVE API BASIC FUNCTIONS pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); pcre *pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr); pcre_extra *pcre_study(const pcre *code, int options, const char **errptr); void pcre_free_study(pcre_extra *extra); int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize, int *workspace, int wscount); PCRE NATIVE API STRING EXTRACTION FUNCTIONS int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int buffersize); int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int buffersize); int pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr); 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); int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr); void pcre_free_substring(const char *stringptr); void pcre_free_substring_list(const char **stringptr); PCRE NATIVE API AUXILIARY FUNCTIONS pcre_jit_stack *pcre_jit_stack_alloc(int startsize, int maxsize); void pcre_jit_stack_free(pcre_jit_stack *stack); void pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *data); const unsigned char *pcre_maketables(void); int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where); int pcre_refcount(pcre *code, int adjust); int pcre_config(int what, void *where); const char *pcre_version(void); int pcre_pattern_to_host_byte_order(pcre *code, pcre_extra *extra, const unsigned char *tables); PCRE NATIVE API INDIRECTED FUNCTIONS void *(*pcre_malloc)(size_t); void (*pcre_free)(void *); void *(*pcre_stack_malloc)(size_t); void (*pcre_stack_free)(void *); int (*pcre_callout)(pcre_callout_block *); PCRE 8-BIT AND 16-BIT LIBRARIES From release 8.30, PCRE can be compiled as a library for handling 16-bit character strings as well as, or instead of, the original library that handles 8-bit character strings. To avoid too much compli- cation, this document describes the 8-bit versions of the functions, with only occasional references to the 16-bit library. The 16-bit functions operate in the same way as their 8-bit counter- parts; they just use different data types for their arguments and results, and their names start with pcre16_ instead of pcre_. For every option that has UTF8 in its name (for example, PCRE_UTF8), there is a corresponding 16-bit name with UTF8 replaced by UTF16. This facility is in fact just cosmetic; the 16-bit option names define the same bit val- ues. References to bytes and UTF-8 in this document should be read as refer- ences to 16-bit data quantities and UTF-16 when using the 16-bit library, unless specified otherwise. More details of the specific dif- ferences for the 16-bit library are given in the pcre16 page. PCRE API OVERVIEW PCRE has its own native API, which is described in this document. There are also some wrapper functions (for the 8-bit library only) that cor- respond to the POSIX regular expression API, but they do not give access to all the functionality. They are described in the pcreposix documentation. Both of these APIs define a set of C function calls. A C++ wrapper (again for the 8-bit library only) is also distributed with PCRE. It is documented in the pcrecpp page. The native API C function prototypes are defined in the header file pcre.h, and on Unix-like systems the (8-bit) library itself is called libpcre. It can normally be accessed by adding -lpcre to the command for linking an application that uses PCRE. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release numbers for the library. Applications can use these to include support for different releases of PCRE. In a Windows environment, if you want to statically link an application program against a non-dll pcre.a file, you must define PCRE_STATIC before including pcre.h or pcrecpp.h, because otherwise the pcre_mal- loc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. The functions pcre_compile(), pcre_compile2(), pcre_study(), and pcre_exec() are used for compiling and matching regular expressions in a Perl-compatible manner. A sample program that demonstrates the sim- plest way of using them is provided in the file called pcredemo.c in the PCRE source distribution. A listing of this program is given in the pcredemo documentation, and the pcresample documentation describes how to compile and run it. Just-in-time compiler support is an optional feature of PCRE that can be built in appropriate hardware environments. It greatly speeds up the matching performance of many patterns. Simple programs can easily request that it be used if available, by setting an option that is ignored when it is not relevant. More complicated programs might need to make use of the functions pcre_jit_stack_alloc(), pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control the JIT code's memory usage. These functions are discussed in the pcrejit documentation. 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. The alternative algorithm finds all possible matches (at a given point in the subject), and scans the subject just once (unless there are lookbehind assertions). 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. In addition to the main compiling and matching functions, there are convenience functions for extracting captured substrings from a subject string that is matched by pcre_exec(). They are: pcre_copy_substring() pcre_copy_named_substring() pcre_get_substring() 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. The function pcre_maketables() is used to build a set of character tables in the current locale for passing to pcre_compile(), pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is provided for specialist use. Most commonly, no special tables are passed, in which case internal tables that are generated when PCRE is built are used. The function pcre_fullinfo() is used to find out information about a compiled pattern. The function pcre_version() returns a pointer to a string containing the version of PCRE and its date of release. The function pcre_refcount() maintains a reference count in a data block containing a compiled pattern. This is provided for the benefit of object-oriented applications. The global variables pcre_malloc and pcre_free initially contain the entry points of the standard malloc() and free() functions, respec- tively. PCRE calls the memory management functions via these variables, so a calling program can replace them if it wishes to intercept the calls. This should be done before calling any PCRE functions. The global variables pcre_stack_malloc and pcre_stack_free are also 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. 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 specified points during a matching operation. Details are given in the pcrecallout documentation. NEWLINES PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (line- feed) character, the two-character sequence CRLF, any of the three pre- ceding, or any Unicode newline sequence. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). Each of the first three conventions is used by at least one operating system as its standard newline sequence. When PCRE is built, a default can be specified. The default default is LF, which is the Unix stan- dard. When PCRE is run, the default can be overridden, either when a pattern is compiled, or when it is matched. At compile time, the newline convention can be specified by the options argument of pcre_compile(), or it can be specified by special text at the start of the pattern itself; this overrides any other settings. See the pcrepattern page for details of the special character sequences. In the PCRE documentation the word "newline" is used to mean "the char- acter or pair of characters that indicate a line break". The choice of newline convention affects the handling of the dot, circumflex, and dollar metacharacters, the handling of #-comments in /x mode, and, when CRLF is a recognized line ending sequence, the match position advance- ment for a non-anchored pattern. There is more detail about this in the section on pcre_exec() options below. The choice of newline convention does not affect the interpretation of the \n or \r escape sequences, nor does it affect what \R matches, which is controlled in a similar way, but by separate options. MULTITHREADING 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- ing, so the same compiled pattern can safely be used by several threads at once. If the just-in-time optimization feature is being used, it needs sepa- rate memory stack areas for each thread. See the pcrejit documentation for more details. 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 pcreprecompile documentation, which includes a description of the pcre_pattern_to_host_byte_order() function. However, compiling a regu- lar expression with one version of PCRE for use with a different ver- sion is not guaranteed to work and may cause crashes. CHECKING BUILD-TIME OPTIONS int pcre_config(int what, void *where); 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- tures. 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 returned value is zero on success, or the negative error code PCRE_ERROR_BADOPTION if the value in the first argument is not recognized. The following information is available: PCRE_CONFIG_UTF8 The output is an integer that is set to one if UTF-8 support is avail- able; otherwise it is set to zero. If this option is given to the 16-bit version of this function, pcre16_config(), the result is PCRE_ERROR_BADOPTION. PCRE_CONFIG_UTF16 The output is an integer that is set to one if UTF-16 support is avail- able; otherwise it is set to zero. This value should normally be given to the 16-bit version of this function, pcre16_config(). If it is given to the 8-bit version of this function, the result is PCRE_ERROR_BADOP- TION. PCRE_CONFIG_UNICODE_PROPERTIES 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_JIT The output is an integer that is set to one if support for just-in-time compiling is available; otherwise it is set to zero. PCRE_CONFIG_JITTARGET The output is a pointer to a zero-terminated "const char *" string. If JIT support is available, the string contains the name of the architec- ture for which the JIT compiler is configured, for example "x86 32bit (little endian + unaligned)". If JIT support is not available, the result is NULL. PCRE_CONFIG_NEWLINE The output is an integer whose value specifies the default character sequence that is recognized as meaning "newline". The four values that are supported are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for ANYCRLF, and -1 for ANY. Though they are derived from ASCII, the same values are returned in EBCDIC environments. The default should normally corre- spond to the standard sequence for your operating system. PCRE_CONFIG_BSR The output is an integer whose value indicates what character sequences the \R escape sequence matches by default. A value of 0 means that \R matches any Unicode line ending sequence; a value of 1 means that \R matches only CR, LF, or CRLF. The default can be overridden when a pat- tern is compiled or matched. PCRE_CONFIG_LINK_SIZE The output is an integer that contains the number of bytes used for internal linkage in compiled regular expressions. For the 8-bit library, the value can be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still a number of bytes. 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. Larger values allow larger regular expressions to be compiled, at the expense of slower matching. 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 given in the pcreposix documentation. PCRE_CONFIG_MATCH_LIMIT The output is a long integer that gives the default limit for the num- ber of 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 a long 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 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 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 blocks on the heap, thus avoiding the use of the stack. COMPILING A PATTERN pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); pcre *pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr); 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, errorcodeptr, via which a numerical error code can be returned. To avoid too much repetition, we refer just to pcre_compile() below, but the information applies equally to pcre_compile2(). 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 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 (via pcre_free) when it is no longer required. 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- ment, which is an address (see below). The options argument contains various bit settings that affect the com- pilation. 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, but some others as well) can also be set and unset from within the pattern (see the detailed description in the pcrepattern documentation). For those options that can be different in different parts of the pattern, the contents of the options argument specifies their settings at the start of compilation and execution. The PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and PCRE_NO_START_OPTIMIZE 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 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. Normally, the offset from the start of the pattern to the byte that was being processed when 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 given). However, for an invalid UTF-8 string, the offset is that of the first byte of the failing character. Some errors are not detected until the whole pattern has been scanned; in these cases, the offset passed back is the length of the pattern. Note that the offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point into the middle of a UTF-8 character. 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 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- pile(): pcre *re; const char *error; int erroffset; re = pcre_compile( "^A.*Z", /* the pattern */ 0, /* default options */ &error, /* for error message */ &erroffset, /* for error offset */ NULL); /* use default character tables */ 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 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 callout facility, see the pcrecallout documentation. PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE These options (which are mutually exclusive) control what the \R escape sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. The default is specified when PCRE is built. It can be overridden from within the pattern, or by set- ting an option when a compiled pattern is matched. 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 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 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 metacharacter in the pattern matches a char- acter of any value, including one that indicates a newline. However, it only ever matches one character, even if newlines are coded as CRLF. Without this option, 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 newline characters, independent of the set- ting 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, white space 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, 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. Which characters are interpreted as newlines is controlled by the options passed to pcre_compile() or by a special sequence at the start of the pattern, as described in the section entitled "Newline conven- tions" in the pcrepattern documentation. Note that the end of this type of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. This option makes it possible to include comments inside complicated patterns. Note, however, that this applies only to data characters. White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that intro- duces 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. (Perl can, however, be persuaded to give an error for this, by running it with the -w option.) 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 in the subject string, though the matched text may continue over the newline. PCRE_JAVASCRIPT_COMPAT If this option is set, PCRE's behaviour is changed in some ways so that it is compatible with JavaScript rather than Perl. The changes are as follows: (1) A lone closing square bracket in a pattern causes a compile-time error, because this is illegal in JavaScript (by default it is treated as a data character). Thus, the pattern AB]CD becomes illegal when this option is set. (2) At run time, a back reference to an unset subpattern group matches an empty string (by default this causes the current matching alterna- tive to fail). A pattern such as (\1)(a) succeeds when this option is set (assuming it can find an "a" in the subject), whereas it fails by default, for Perl compatibility. (3) \U matches an upper case "U" character; by default \U causes a com- pile time error (Perl uses \U to upper case subsequent characters). (4) \u matches a lower case "u" character unless it is followed by four hexadecimal digits, in which case the hexadecimal number defines the code point to match. By default, \u causes a compile time error (Perl uses it to upper case the following character). (5) \x matches a lower case "x" character unless it is followed by two hexadecimal digits, in which case the hexadecimal number defines the code point to match. By default, as in Perl, a hexadecimal number is always expected after \x, but it may have zero, one, or two digits (so, for example, \xz matches a binary zero character followed by z). PCRE_MULTILINE By default, PCRE treats the subject string as consisting of a single line of characters (even if it actually contains newlines). The "start of line" metacharacter (^) matches only at the start of the string, while the "end of line" metacharacter ($) matches only at the end of the string, or before a terminating newline (unless PCRE_DOLLAR_ENDONLY 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 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 PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY 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 PCRE_NEWLINE_CRLF specifies that a newline is indicated by the two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies that any of the three preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit library, the last two are recognized only in UTF-8 mode. The newline setting in the options word uses three bits that are treated as a number, giving eight possibilities. Currently only six are used (default plus the five values above). This means that if you set more than one newline option, the combination may or may not be sensi- ble. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and cause an error. The only time that a line break in a pattern is specially recognized when compiling is when PCRE_EXTENDED is set. CR and LF are white space characters, and so are ignored in this mode. Also, an unescaped # out- side a character class indicates a comment that lasts until after the next line break sequence. In other circumstances, line break sequences in patterns are treated as literal data. The newline option that is 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). There is no equivalent of this option in Perl. NO_START_OPTIMIZE This is an option that acts at matching time; that is, it is really an option for pcre_exec() or pcre_dfa_exec(). If it is set at compile time, it is remembered with the compiled pattern and assumed at match- ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE below. PCRE_UCP This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, \w, and some of the POSIX character classes. By default, only ASCII characters are recognized, but if PCRE_UCP is set, Unicode properties are used instead to classify characters. More details are given in the section on generic character types in the pcrepattern page. If you set PCRE_UCP, matching one of the items it affects takes much longer. The option is available only if PCRE has been compiled with Unicode prop- erty support. 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 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 strings. However, it is available only when PCRE is built to include UTF support. If not, the use of this option provokes an error. Details of how this option changes the behaviour of PCRE are given in the pcreunicode page. PCRE_NO_UTF8_CHECK When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is automatically checked. There is a discussion about the validity of UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence 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 rea- sons, 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 validity checking 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 both compiling functions. Note that error messages are always 8-bit ASCII strings, even in 16-bit mode. As PCRE has developed, some error codes have fallen out of use. To avoid confusion, they have not been re-used. 0 no error 1 \ at end of pattern 2 \c at end of pattern 3 unrecognized character follows \ 4 numbers out of order in {} quantifier 5 number too big in {} quantifier 6 missing terminating ] for character class 7 invalid escape sequence in character class 8 range out of order in character class 9 nothing to repeat 10 [this code is not in use] 11 internal error: unexpected repeat 12 unrecognized character after (? or (?- 13 POSIX named classes are supported only within a class 14 missing ) 15 reference to non-existent subpattern 16 erroffset passed as NULL 17 unknown option bit(s) set 18 missing ) after comment 19 [this code is not in use] 20 regular expression is too large 21 failed to get memory 22 unmatched parentheses 23 internal error: code overflow 24 unrecognized character after (?< 25 lookbehind assertion is not fixed length 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 ) 30 unknown POSIX class name 31 POSIX collating elements are not supported 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] 34 character value in \x{...} sequence is too large 35 invalid condition (?(0) 36 \C not allowed in lookbehind assertion 37 PCRE does not support \L, \l, \N{name}, \U, or \u 38 number after (?C is > 255 39 closing ) for (?C expected 40 recursive call could loop indefinitely 41 unrecognized character after (?P 42 syntax error in subpattern name (missing terminator) 43 two named subpatterns have the same name 44 invalid UTF-8 string (specifically UTF-8) 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 10000) 50 [this code is not in use] 51 octal value is greater than \377 in 8-bit non-UTF-8 mode 52 internal error: overran compiling workspace 53 internal error: previously-checked referenced subpattern not found 54 DEFINE group contains more than one branch 55 repeating a DEFINE group is not allowed 56 inconsistent NEWLINE options 57 \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number 58 a numbered reference must not be zero 59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) 60 (*VERB) not recognized 61 number is too big 62 subpattern name expected 63 digit expected after (?+ 64 ] is an invalid data character in JavaScript compatibility mode 65 different names for subpatterns of the same number are not allowed 66 (*MARK) must have an argument 67 this version of PCRE is not compiled with Unicode property support 68 \c must be followed by an ASCII character 69 \k is not followed by a braced, angle-bracketed, or quoted name 70 internal error: unknown opcode in find_fixedlength() 71 \N is not supported in a class 72 too many forward references 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff) 74 invalid UTF-16 string (specifically UTF-16) 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) 76 character value in \u.... sequence is too large The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. 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 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- 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 the results of the study. The returned value from pcre_study() can be passed directly to pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con- tains 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 useful information, pcre_study() returns NULL. In that circumstance, if the calling program wants to pass any of the other fields to pcre_exec() or pcre_dfa_exec(), it must set up its own pcre_extra block. The second argument of pcre_study() contains option bits. There are three options: PCRE_STUDY_JIT_COMPILE PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE If any of these are set, and the just-in-time compiler is available, the pattern is further compiled into machine code that executes much faster than the pcre_exec() interpretive matching function. If the just-in-time compiler is not available, these options are ignored. All other bits in the options argument must be zero. JIT compilation is a heavyweight optimization. It can take some time for patterns to be analyzed, and for one-off matches and simple pat- terns the benefit of faster execution might be offset by a much slower study time. Not all patterns can be optimized by the JIT compiler. For those that cannot be handled, matching automatically falls back to the pcre_exec() interpreter. For more details, see the pcrejit documenta- tion. 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 after calling pcre_study(), to be sure that it has run successfully. When you are finished with a pattern, you can free the memory used for the study data by calling pcre_free_study(). This function was added to the API for release 8.20. For earlier versions, the memory could be freed with pcre_free(), just like the pattern itself. This will still work in cases where JIT optimization is not used, but it is advisable to change to the new function when convenient. This is a typical way in which pcre_study() is used (except that in a real application there should be tests for errors): int rc; pcre *re; pcre_extra *sd; re = pcre_compile("pattern", 0, &error, &erroroffset, NULL); sd = pcre_study( re, /* result of pcre_compile() */ 0, /* no options */ &error); /* set to NULL or points to a message */ rc = pcre_exec( /* see below for details of pcre_exec() options */ re, sd, "subject", 7, 0, 0, ovector, 30); ... pcre_free_study(sd); pcre_free(re); Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not mean that there are any strings of that length that match, but it does guarantee that no shorter strings match. The value is used by pcre_exec() and pcre_dfa_exec() to avoid wasting time by trying to match strings that are shorter than the lower bound. You can find out the value in a calling program via the pcre_fullinfo() function. Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at which to start matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256.) These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), and the information is also used by the JIT compiler. The optimiza- tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_exec() or pcre_dfa_exec(), but if this is done, JIT execu- tion is also disabled. You might want to do this if your pattern con- tains callouts or (*MARK) and you want to make use of these facilities in cases where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE below. 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. By default, higher-valued codes never match escapes such as \w or \d, but they can be tested with \p if PCRE is built with Unicode character property support. Alternatively, the PCRE_UCP option can be set at compile time; this causes \w and friends to use Unicode property support instead of built-in tables. The use of locales with Unicode is discouraged. If you are handling charac- ters with codes greater than 128, you should either use UTF-8 and Uni- code, or use locales, but not try to mix the two. PCRE contains an internal set of tables that are used when the final argument of pcre_compile() is NULL. These are sufficient for many applications. Normally, the internal tables recognize only ASCII char- acters. However, when PCRE is built, it is possible to cause the inter- nal tables to be rebuilt in the default "C" locale of the local system, which may cause them to be different. The internal tables can always be overridden by tables supplied by the application that calls PCRE. These may be created in a different locale from the default. As more and more applications change to using Uni- code, 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 treated as letters), the following code could be used: setlocale(LC_CTYPE, "fr_FR"); tables = pcre_maketables(); re = pcre_compile(..., tables); The locale name "fr_FR" is used on Linux and other Unix-like systems; if you are using Windows, the name for the French locale is "french". 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() 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 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. 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- tern. It replaces the pcre_info() function, which was removed from the library at version 8.30, after more than 10 years of obsolescence. 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 the argument where was NULL PCRE_ERROR_BADMAGIC the "magic number" was not found PCRE_ERROR_BADENDIANNESS the pattern was compiled with different endianness 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. The endi- anness error can occur if a compiled pattern is saved and reloaded on a different host. Here is a typical call of pcre_fullinfo(), to obtain the length of the compiled pattern: int rc; size_t length; rc = pcre_fullinfo( re, /* result of pcre_compile() */ sd, /* 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 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 there are no back references. PCRE_INFO_CAPTURECOUNT 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 information call is provided for internal use by the pcre_study() func- 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 data unit of any matched string, for a non-anchored pattern. (The name of this option refers to the 8-bit library, where data units are bytes.) The fourth argument should point to an int variable. If there is a fixed first value, for example, the letter "c" from a pattern such as (cat|cow|coyote), its value is returned. In the 8-bit library, the value is always less than 256; in the 16-bit library the value can be up to 0xffff. If there is no fixed first value, and if either (a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set (if it were set, the pattern would be anchored), -1 is returned, indicating that the pattern matches only at the start of a subject string or after any newline within the string. Otherwise -2 is returned. For anchored patterns, -2 is returned. PCRE_INFO_FIRSTTABLE If the pattern was studied, and this resulted in the construction of a 256-bit table indicating a fixed set of values for the first data unit in any matching string, a pointer to the table is returned. Otherwise NULL is returned. The fourth argument should point to an unsigned char * variable. PCRE_INFO_HASCRORLF Return 1 if the pattern contains any explicit matches for CR or LF characters, otherwise 0. The fourth argument should point to an int variable. An explicit match is either a literal CR or LF character, or \r or \n. PCRE_INFO_JCHANGED Return 1 if the (?J) or (?-J) option setting is used in the pattern, otherwise 0. The fourth argument should point to an int variable. (?J) and (?-J) set and unset the local PCRE_DUPNAMES option, respectively. PCRE_INFO_JIT Return 1 if the pattern was studied with one of the JIT options, and just-in-time compiling was successful. The fourth argument should point to an int variable. A return value of 0 means that JIT support is not available in this version of PCRE, or that the pattern was not studied with a JIT option, or that the JIT compiler could not handle this par- ticular pattern. See the pcrejit documentation for details of what can and cannot be handled. PCRE_INFO_JITSIZE If the pattern was successfully studied with a JIT option, return the size of the JIT compiled code, otherwise return zero. The fourth argu- ment should point to a size_t variable. PCRE_INFO_LASTLITERAL Return the value of the rightmost literal data unit that must exist in any matched string, other than at its start, if such a value has been recorded. The fourth argument should point to an int variable. If there is no such value, -1 is returned. For anchored patterns, a last literal value is recorded only if it follows something of variable length. For example, for the pattern /^a\d+z\d+/ the returned value is "z", but for /^a\dz\d/ the returned value is -1. PCRE_INFO_MAXLOOKBEHIND Return the number of characters (NB not bytes) in the longest lookbe- hind assertion in the pattern. Note that the simple assertions \b and \B require a one-character lookbehind. This information is useful when doing multi-segment matching using the partial matching facilities. PCRE_INFO_MINLENGTH If the pattern was studied and a minimum length for matching subject strings was computed, its value is returned. Otherwise the returned value is -1. The value is a number of characters, which in UTF-8 mode may be different from the number of bytes. The fourth argument should point to an int variable. A non-negative value is a lower bound to the length of any matching string. There may not be any strings of that length that do actually match, but every string that does match is at least that long. PCRE_INFO_NAMECOUNT PCRE_INFO_NAMEENTRYSIZE PCRE_INFO_NAMETABLE 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. 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 of each entry; both of these return an int value. The entry size depends on the length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first entry of the table. This is a pointer to char in the 8-bit library, where the first two bytes of each entry are the num- ber of the capturing parenthesis, most significant byte first. In the 16-bit library, the pointer points to 16-bit data units, the first of which contains the parenthesis number. The rest of the entry is the corresponding name, zero terminated. The names are in alphabetical order. Duplicate names may appear if (?| is used to create multiple groups with the same number, as described in the section on duplicate subpattern numbers in the pcrepattern page. Duplicate names for subpatterns with different numbers are permitted only if PCRE_DUPNAMES is set. In all cases of duplicate names, they appear in the table in the order in which they were found in the pat- tern. In the absence of (?| this is the order of increasing number; when (?| is used this is not necessarily the case because later subpat- terns may have lower numbers. As a simple example of the name/number table, consider the following pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white space - including newlines - is ignored): (? (?(\d\d)?\d\d) - (?\d\d) - (?\d\d) ) There are four named subpatterns, so the table has four entries, and each entry in the table is eight bytes long. The table is as follows, with non-printing bytes shows in hexadecimal, and undefined bytes shown as ??: 00 01 d a t e 00 ?? 00 05 d a y 00 ?? ?? 00 04 m o n t h 00 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 the entries is likely to be different for each compiled pattern. PCRE_INFO_OKPARTIAL Return 1 if the pattern can be used for partial matching with pcre_exec(), otherwise 0. The fourth argument should point to an int variable. From release 8.00, this always returns 1, because the restrictions that previously applied to partial matching have been lifted. The pcrepartial documentation gives details of partial match- ing. PCRE_INFO_OPTIONS Return a copy of the options with which the pattern was compiled. The fourth argument should point to an unsigned long int variable. These option bits are those specified in the call to pcre_compile(), modified by any top-level option settings at the start of the pattern itself. In other words, they are the options that will be in force when matching starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, and PCRE_EXTENDED. A pattern is automatically anchored by PCRE if all of its top-level alternatives begin with one of the following: ^ unless PCRE_MULTILINE is set \A always \G always .* if PCRE_DOTALL is set and there are no back references to the subpattern in which .* appears For such patterns, the PCRE_ANCHORED bit is set in the options returned by pcre_fullinfo(). PCRE_INFO_SIZE Return the size of the compiled pattern in bytes (for both libraries). The fourth argument should point to a size_t variable. This value does not include the size of the pcre structure that is returned by pcre_compile(). The value that is passed as the argument to pcre_mal- loc() when pcre_compile() is getting memory in which to place the com- piled data is the value returned by this option plus the size of the pcre structure. Studying a compiled pattern, with or without JIT, does not alter the value returned by this option. PCRE_INFO_STUDYSIZE Return the size in bytes of the data block pointed to by the study_data field in a pcre_extra block. If pcre_extra is NULL, or there is no study data, zero is returned. The fourth argument should point to a size_t variable. The study_data field is set by pcre_study() to record information that will speed up matching (see the section entitled "Studying a pattern" above). The format of the study_data block is pri- vate, but its length is made available via this option so that it can be saved and restored (see the pcreprecompile documentation for details). REFERENCE COUNTS int pcre_refcount(pcre *code, int adjust); The pcre_refcount() function is used to maintain a reference count in the data block that contains a compiled pattern. It is provided for the benefit of applications that operate in an object-oriented manner, where different parts of the application may be using the same compiled pattern, but you want to free the block when they are all done. When a pattern is compiled, the reference count field is initialized to zero. It is changed only by calling this function, whose action is to add the adjust value (which may be positive or negative) to it. The yield of the function is the new value. However, the value of the count is constrained to lie between 0 and 65535, inclusive. If the new value is outside these limits, it is forced to the appropriate limit value. Except when it is zero, the reference count is not correctly preserved if a pattern is compiled on one host and then transferred to a host whose byte-order is different. (This seems a highly unlikely scenario.) MATCHING A PATTERN: THE TRADITIONAL FUNCTION int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); The function pcre_exec() is called to match a subject string against a compiled pattern, which is passed in the code argument. If the pattern was studied, the result of the study should be passed in the extra argument. You can call pcre_exec() with the same code and extra argu- ments as many times as you like, in order to match different subject strings with the same pattern. This function is the main matching facility of the library, and it operates in a Perl-like manner. For specialist use there is also an alternative matching function, which is described below in the section about the pcre_dfa_exec() function. In most applications, the pattern will have been compiled (and option- ally studied) in the same process that calls pcre_exec(). However, it is possible to save compiled patterns and study data, and then use them later in different processes, possibly even on different hosts. For a discussion about this, see the pcreprecompile documentation. Here is an example of a simple call to pcre_exec(): int rc; int ovector[30]; rc = pcre_exec( re, /* result of pcre_compile() */ NULL, /* we didn't study the pattern */ "some string", /* the subject string */ 11, /* the length of the subject string */ 0, /* start at offset 0 in the subject */ 0, /* default options */ ovector, /* vector of integers for substring information */ 30); /* number of elements (NOT size in bytes) */ Extra data for pcre_exec() If the extra argument is not NULL, it must point to a pcre_extra data block. The pcre_study() function returns such a block (when it doesn't return NULL), but you can also create one for yourself, and pass addi- tional information in it. The pcre_extra block contains the following fields (not necessarily in this order): unsigned long int flags; void *study_data; void *executable_jit; unsigned long int match_limit; unsigned long int match_limit_recursion; void *callout_data; const unsigned char *tables; unsigned char **mark; In the 16-bit version of this structure, the mark field has type "PCRE_UCHAR16 **". The flags field is used to specify which of the other fields are set. The flag bits are: PCRE_EXTRA_CALLOUT_DATA PCRE_EXTRA_EXECUTABLE_JIT PCRE_EXTRA_MARK PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_MATCH_LIMIT_RECURSION PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_TABLES Other flag bits should be set to zero. The study_data field and some- times the executable_jit field are set in the pcre_extra block that is returned by pcre_study(), together with the appropriate flag bits. You should not set these yourself, but you may add to the block by setting other fields and their corresponding flag bits. The match_limit field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlim- ited repeats. Internally, pcre_exec() uses a function called match(), which it calls repeatedly (sometimes recursively). The limit set by match_limit is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. For patterns that are not anchored, the count restarts from zero for each position in the subject string. When pcre_exec() is called with a pattern that was successfully studied with a JIT option, the way that the matching is executed is entirely different. However, there is still the possibility of runaway matching that goes on for a very long time, and so the match_limit value is also used in this case (but in a different way) to limit how long the match- ing can continue. The default value for the limit can be set when PCRE is built; the default default is 10 million, which handles all but the most extreme cases. You can override the default by suppling pcre_exec() with a pcre_extra block in which match_limit is set, and PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursion. The recursion depth is a smaller number than the total number of calls, because not all calls to match() are recur- sive. This limit is of use only if it is set smaller than match_limit. Limiting the recursion depth limits the amount of machine stack that can be used, or, when PCRE has been compiled to use memory on the heap instead of the stack, the amount of heap memory that can be used. This limit is not relevant, and is ignored, when matching is done using JIT compiled code. The default value for match_limit_recursion can be set when PCRE is built; the default default is the same value as the default for match_limit. You can override the default by suppling pcre_exec() with a pcre_extra block in which match_limit_recursion is set, and PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT. The callout_data field is used in conjunction with the "callout" fea- ture, and is described in the pcrecallout documentation. The tables field is used to pass a character tables pointer to pcre_exec(); this overrides the value that is stored with the compiled pattern. A non-NULL value is stored with the compiled pattern only if custom tables were supplied to pcre_compile() via its tableptr argu- ment. If NULL is passed to pcre_exec() using this mechanism, it forces PCRE's internal tables to be used. This facility is helpful when re- using patterns that have been saved after compiling with an external set of tables, because the external tables might be at a different address when pcre_exec() is called. See the pcreprecompile documenta- tion for a discussion of saving compiled patterns for later use. If PCRE_EXTRA_MARK is set in the flags field, the mark field must be set to point to a suitable variable. If the pattern contains any back- tracking control verbs such as (*MARK:NAME), and the execution ends up with a name to pass back, a pointer to the name string (zero termi- nated) is placed in the variable pointed to by the mark field. The names are within the compiled pattern; if you wish to retain such a name you must copy it before freeing the memory of a compiled pattern. If there is no name to pass back, the variable pointed to by the mark field is set to NULL. For details of the backtracking control verbs, see the section entitled "Backtracking control" in the pcrepattern doc- umentation. 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_NEWLINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If the pattern was successfully studied with one of the just-in-time (JIT) compile options, the only supported options for JIT execution are PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an unsupported option is used, JIT execution is disabled and the normal interpretive code in pcre_exec() is run. 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 unachored at matching time. PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE These options (which are mutually exclusive) control what the \R escape sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. These options override the choice that was made or defaulted when the pattern was compiled. PCRE_NEWLINE_CR PCRE_NEWLINE_LF PCRE_NEWLINE_CRLF PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY These options override the newline definition that was chosen or defaulted when the pattern was compiled. For details, see the descrip- tion of pcre_compile() above. During matching, the newline choice affects the behaviour of the dot, circumflex, and dollar metacharac- ters. It may also alter the way the match position is advanced after a match failure for an unanchored pattern. When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is set, and a match attempt for an unanchored pattern fails when the cur- rent position is at a CRLF sequence, and the pattern contains no explicit matches for CR or LF characters, the match position is advanced by two characters instead of one, in other words, to after the CRLF. The above rule is a compromise that makes the most common cases work as expected. For example, if the pattern is .+A (and the PCRE_DOTALL option is not set), it does not match the string "\r\nA" because, after failing at the start, it skips both the CR and the LF before retrying. However, the pattern [\r\n]A does match that string, because it con- tains an explicit CR or LF reference, and so advances only by one char- acter after the first failure. An explicit match for CR of LF is either a literal appearance of one of those characters, or one of the \r or \n escape sequences. Implicit matches such as [^X] do not count, nor does \s (which includes CR and LF in the characters that it matches). Notwithstanding the above, anomalous effects may still occur when CRLF is a valid newline sequence and explicit \r or \n escapes appear in the pattern. PCRE_NOTBOL This option specifies that first character of the subject string is not the beginning of a line, so the circumflex metacharacter should not match before it. Setting this without PCRE_MULTILINE (at compile time) causes circumflex never to match. This option affects only the behav- iour of the circumflex metacharacter. It does not affect \A. PCRE_NOTEOL This option specifies that the end of the subject string is not the end of a line, so the dollar metacharacter should not match it nor (except in multiline mode) a newline immediately before it. Setting this with- out PCRE_MULTILINE (at compile time) causes dollar never to match. This option affects only the behaviour of the dollar metacharacter. It does not affect \Z or \z. PCRE_NOTEMPTY An empty string is not considered to be a valid match if this option is set. If there are alternatives in the pattern, they are tried. If all the alternatives match the empty string, the entire match fails. For example, if the pattern a?b? is applied to a string not beginning with "a" or "b", it matches an empty string at the start of the subject. With PCRE_NOTEMPTY set, this match is not valid, so PCRE searches further into the string for occur- rences of "a" or "b". PCRE_NOTEMPTY_ATSTART This is like PCRE_NOTEMPTY, except that an empty string match that is not at the start of the subject is permitted. If the pattern is anchored, such a match can occur only if the pattern contains \K. Perl has no direct equivalent of PCRE_NOTEMPTY or PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern match of the empty string within its split() function, and when using the /g modifier. It is possible to emulate Perl's behaviour after matching a null string by first trying the match again at the same off- set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that fails, by advancing the starting offset (see below) and trying an ordi- nary match again. There is some code that demonstrates how to do this in the pcredemo sample program. In the most general case, you have to check to see if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. PCRE_NO_START_OPTIMIZE There are a number of optimizations that pcre_exec() uses at the start of a match, in order to speed up the process. For example, if it is known that an unanchored match must start with a specific character, it searches the subject for that character, and fails immediately if it cannot find it, without actually running the main matching function. This means that a special item such as (*COMMIT) at the start of a pat- tern is not considered until after a suitable starting point for the match has been found. When callouts or (*MARK) items are in use, these "start-up" optimizations can cause them to be skipped if the pattern is never actually used. The start-up optimizations are in effect a pre- scan of the subject that takes place before the pattern is run. The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly causing performance to suffer, but ensuring that in cases where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching is always done using interpretively. Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern (*COMMIT)ABC When this is compiled, PCRE records the fact that a match must start with the character "A". Suppose the subject string is "DEFABC". The start-up optimization scans along the subject, finds "A" and runs the first match attempt from there. The (*COMMIT) item means that the pat- tern must match the current starting position, which in this case, it does. However, if the same match is run with PCRE_NO_START_OPTIMIZE set, the initial scan along the subject string does not happen. The first match attempt is run starting from "D" and when this fails, (*COMMIT) prevents any further matches being tried, so the overall result is "no match". If the pattern is studied, more start-up opti- mizations may be used. For example, a minimum length for the subject may be recorded. Consider the pattern (*MARK:A)(X|Y) The minimum length for a match is one character. If the subject is "ABC", there will be attempts to match "ABC", "BC", "C", and then finally an empty string. If the pattern is studied, the final attempt does not take place, because PCRE knows that the subject is too short, and so the (*MARK) is never encountered. In this case, studying the pattern does not affect the overall match result, which is still "no match", but it does affect the auxiliary information that is returned. PCRE_NO_UTF8_CHECK When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8 string is automatically checked when pcre_exec() is subsequently called. The entire string is checked before any other processing takes place. The value of startoffset is also checked to ensure that it points to the start of a UTF-8 character. There is a discussion about the validity of UTF-8 strings in the pcreunicode page. If an invalid sequence of bytes is found, pcre_exec() returns the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In both cases, information about the precise nature of the error may also be returned (see the descriptions of these errors in the section enti- tled Error return values from pcre_exec() below). If startoffset con- tains a value that does not point to the start of a UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. If you already know that your subject is valid, and you want to skip these checks for performance reasons, you can set the PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to do this for the second and subsequent calls to pcre_exec() if you are making repeated calls to find all the matches in a single subject string. However, you should be sure that the value of startoffset points to the start of a character (or the end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a subject or an invalid value of startoffset is undefined. Your program may crash. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT These options turn on the partial matching feature. For backwards com- patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial match occurs if the end of the subject string is reached successfully, but there are not enough subject characters to complete the match. If this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set, matching continues by testing any remaining alternatives. Only if no complete match can be found is PCRE_ERROR_PARTIAL returned instead of PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the caller is prepared to handle a partial match, but only if no complete match can be found. If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this case, if a partial match is found, pcre_exec() immediately returns PCRE_ERROR_PARTIAL, without considering any other alternatives. In other words, when PCRE_PARTIAL_HARD is set, a partial match is consid- ered to be more important that an alternative complete match. In both cases, the portion of the string that was inspected when the partial match was found is set as the first matching string. There is a more detailed discussion of partial and multi-segment matching, with examples, in the pcrepartial documentation. The string to be matched by pcre_exec() The subject string is passed to pcre_exec() as a pointer in subject, a length in bytes in length, and a starting byte offset in startoffset. If this is negative or greater than the length of the subject, pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is zero, the search for a match starts at the beginning of the subject, and this is by far the most common case. In UTF-8 mode, the byte offset must point to the start of a UTF-8 character (or the end of the sub- ject). Unlike the pattern string, the subject may contain binary zero bytes. A non-zero starting offset is useful when searching for another match in the same subject by calling pcre_exec() again after a previous suc- cess. Setting startoffset differs from just passing over a shortened string and setting PCRE_NOTBOL in the case of a pattern that begins with any kind of lookbehind. For example, consider the pattern \Biss\B which finds occurrences of "iss" in the middle of words. (\B matches only if the current position in the subject is not a word boundary.) When applied to the string "Mississipi" the first call to pcre_exec() finds the first occurrence. If pcre_exec() is called again with just the remainder of the subject, namely "issipi", it does not match, because \B is always false at the start of the subject, which is deemed to be a word boundary. However, if pcre_exec() is passed the entire string again, but with startoffset set to 4, it finds the second occur- rence of "iss" because it is able to look behind the starting point to discover that it is preceded by a letter. Finding all the matches in a subject is tricky when the pattern can match an empty string. It is possible to emulate Perl's /g behaviour by first trying the match again at the same offset, with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that fails, advancing the starting offset and trying an ordinary match again. There is some code that demonstrates how to do this in the pcre- demo sample program. In the most general case, you have to check to see if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. If a non-zero starting offset is passed when the pattern is anchored, one attempt to match at the given offset is made. This can only succeed if the pattern does not require the match to be at the start of the subject. How pcre_exec() returns captured substrings In general, a pattern matches a certain portion of the subject, and in addition, further substrings from the subject may be picked out by parts of the pattern. Following the usage in Jeffrey Friedl's book, this is called "capturing" in what follows, and the phrase "capturing subpattern" is used for a fragment of a pattern that picks out a sub- string. PCRE supports several other kinds of parenthesized subpattern that do not cause substrings to be captured. Captured substrings are returned to the caller via a vector of integers whose address is passed in ovector. The number of elements in the vec- tor is passed in ovecsize, which must be a non-negative number. Note: this argument is NOT the size of ovector in bytes. The first two-thirds of the vector is used to pass back captured sub- strings, each substring using a pair of integers. The remaining third of the vector is used as workspace by pcre_exec() while matching cap- turing subpatterns, and is not available for passing back information. The number passed in ovecsize should always be a multiple of three. If it is not, it is rounded down. When a match is successful, information about captured substrings is returned in pairs of integers, starting at the beginning of ovector, and continuing up to two-thirds of its length at the most. The first element of each pair is set to the byte offset of the first character in a substring, and the second is set to the byte offset of the first character after the end of a substring. Note: these values are always byte offsets, even in UTF-8 mode. They are not character counts. The first pair of integers, ovector[0] and ovector[1], identify the portion of the subject string matched by the entire pattern. The next pair is used for the first capturing subpattern, 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, it is used as far as possible (up to two-thirds of its length), and the function returns a value of zero. If neither the actual string matched nor any captured substrings are of interest, pcre_exec() may be called with ovector passed as NULL and ovecsize as zero. However, if the pat- tern 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 of reasonable size. There are some cases where zero is returned (indicating vector over- flow) when in fact the vector is exactly the right size for the final match. For example, consider the pattern (a)(?:(b)c|bd) If a vector of 6 elements (allowing for only 1 captured substring) is given with subject string "abd", pcre_exec() will try to set the second captured string, thereby recording a vector overflow, before failing to match "c" and backing up to try the second alternative. The zero return, however, does correctly indicate that the maximum number of slots (namely 2) have been filled. In similar cases where there is tem- porary overflow, but the final number of used slots is actually less than the maximum, a non-zero value is returned. The pcre_fullinfo() 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, and the offsets for for the second and third capturing subpatterns (assuming the vector is large enough, of course) are set to -1. Note: Elements in the first two-thirds of ovector that do not corre- spond to capturing parentheses in the pattern are never changed. That is, if a pattern contains n capturing parentheses, no more than ovec- tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in the first two-thirds) retain whatever values they previously had. Some convenience functions are provided for extracting the captured substrings as separate strings. These are described below. 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) The subject string did not match the pattern. PCRE_ERROR_NULL (-2) Either code or subject was passed as NULL, or ovector was NULL and ovecsize was not zero. PCRE_ERROR_BADOPTION (-3) An unrecognized bit was set in the options argument. PCRE_ERROR_BADMAGIC (-4) 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 gives when the magic number is not present. PCRE_ERROR_UNKNOWN_OPCODE (-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 overwriting of the compiled pattern. PCRE_ERROR_NOMEMORY (-6) 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 memory is automatically freed at the end of matching. This error is also given if pcre_stack_malloc() fails in pcre_exec(). This can happen only when PCRE has been compiled with --disable-stack- for-recursion. PCRE_ERROR_NOSUBSTRING (-7) 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 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. See the pcrecallout documentation for details. PCRE_ERROR_BADUTF8 (-10) A string that contains an invalid UTF-8 byte sequence was passed as a subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector (ovecsize) is at least 2, the byte offset to the start of the the invalid UTF-8 character is placed in the first ele- ment, and a reason code is placed in the second element. The reason codes are listed in the following section. For backward compatibility, if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char- acter at the end of the subject (reason codes 1 to 5), PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8. PCRE_ERROR_BADUTF8_OFFSET (-11) The UTF-8 byte sequence that was passed as a subject was checked and found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the value of startoffset did not point to the beginning of a UTF-8 charac- ter or the end of the subject. PCRE_ERROR_PARTIAL (-12) The subject string did not match, but it did match partially. See the pcrepartial documentation for details of partial matching. PCRE_ERROR_BADPARTIAL (-13) This code is no longer in use. It was formerly returned when the PCRE_PARTIAL option was used with a compiled pattern containing items that were not supported for partial matching. From release 8.00 onwards, there are no restrictions on partial matching. PCRE_ERROR_INTERNAL (-14) 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. 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 description above. PCRE_ERROR_BADNEWLINE (-23) An invalid combination of PCRE_NEWLINE_xxx options was given. PCRE_ERROR_BADOFFSET (-24) The value of startoffset was negative or greater than the length of the subject, that is, the value in length. PCRE_ERROR_SHORTUTF8 (-25) This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set. Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but this special error code for PCRE_PARTIAL_HARD precedes the implementa- tion of returned information; it is retained for backwards compatibil- ity. PCRE_ERROR_RECURSELOOP (-26) This error is returned when pcre_exec() detects a recursion loop within the pattern. Specifically, it means that either the whole pattern or a subpattern has been called recursively for the second time at the same position in the subject string. Some simple patterns that might do this are detected and faulted at compile time, but more complicated cases, in particular mutual recursions between two different subpatterns, can- not be detected until run time. PCRE_ERROR_JIT_STACKLIMIT (-27) This error is returned when a pattern that was successfully studied using a JIT compile option is being matched, but the memory available for the just-in-time processing stack is not large enough. See the pcrejit documentation for more details. PCRE_ERROR_BADMODE (-28) This error is given if a pattern that was compiled by the 8-bit library is passed to a 16-bit library function, or vice versa. PCRE_ERROR_BADENDIANNESS (-29) This error is given if a pattern that was compiled and saved is reloaded on a host with different endianness. The utility function pcre_pattern_to_host_byte_order() can be used to convert such a pattern so that it runs on the new host. Error numbers -16 to -20, -22, and -30 are not used by pcre_exec(). Reason codes for invalid UTF-8 strings This section applies only to the 8-bit library. The corresponding information for the 16-bit library is given in the pcre16 page. When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORT- UTF8, and the size of the output vector (ovecsize) is at least 2, the offset of the start of the invalid UTF-8 character is placed in the first output vector element (ovector[0]) and a reason code is placed in the second element (ovector[1]). The reason codes are given names in the pcre.h header file: PCRE_UTF8_ERR1 PCRE_UTF8_ERR2 PCRE_UTF8_ERR3 PCRE_UTF8_ERR4 PCRE_UTF8_ERR5 The string ends with a truncated UTF-8 character; the code specifies how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 characters to be no longer than 4 bytes, the encoding scheme (origi- nally defined by RFC 2279) allows for up to 6 bytes, and this is checked first; hence the possibility of 4 or 5 missing bytes. PCRE_UTF8_ERR6 PCRE_UTF8_ERR7 PCRE_UTF8_ERR8 PCRE_UTF8_ERR9 PCRE_UTF8_ERR10 The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of the character do not have the binary value 0b10 (that is, either the most significant bit is 0, or the next bit is 1). PCRE_UTF8_ERR11 PCRE_UTF8_ERR12 A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long; these code points are excluded by RFC 3629. PCRE_UTF8_ERR13 A 4-byte character has a value greater than 0x10fff; these code points are excluded by RFC 3629. PCRE_UTF8_ERR14 A 3-byte character has a value in the range 0xd800 to 0xdfff; this range of code points are reserved by RFC 3629 for use with UTF-16, and so are excluded from UTF-8. PCRE_UTF8_ERR15 PCRE_UTF8_ERR16 PCRE_UTF8_ERR17 PCRE_UTF8_ERR18 PCRE_UTF8_ERR19 A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes for a value that can be represented by fewer bytes, which is invalid. For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor- rect coding uses just one byte. PCRE_UTF8_ERR20 The two most significant bits of the first byte of a character have the binary value 0b10 (that is, the most significant bit is 1 and the sec- ond is 0). Such a byte can only validly occur as the second or subse- quent byte of a multi-byte character. PCRE_UTF8_ERR21 The first byte of a character has the value 0xfe or 0xff. These values can never occur in a valid UTF-8 string. EXTRACTING CAPTURED SUBSTRINGS BY NUMBER int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int buffersize); int pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr); 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 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. 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 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 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 terminating zero, or one of these error codes: PCRE_ERROR_NOMEMORY (-6) 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 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 pointer. The yield of the function is zero if all went well, or the error code 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 empty string. This can be distinguished from a genuine zero-length sub- 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 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 that cannot use pcre_free directly; it is for these cases that the functions are pro- vided. EXTRACTING CAPTURED SUBSTRINGS BY NAME int pcre_get_stringnumber(const pcre *code, const char *name); int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int buffersize); int pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr); To extract a substring by name, you first have to find associated num- ber. For example, for this pattern (a+)b(?\d+)... 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 are also two functions that do the whole job. Most of the arguments of pcre_copy_named_substring() and pcre_get_named_substring() are the same as those for the similarly named functions that extract by number. As these are described in the previous section, they are not re-described here. There are just two differences: First, instead of a substring number, a substring name is given. Sec- ond, there is an extra argument, given at the start, which is a pointer to the compiled pattern. This is needed in order to gain access to the name-to-number translation table. These functions call pcre_get_stringnumber(), and if it succeeds, they then call pcre_copy_substring() or pcre_get_substring(), as appropri- ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the behaviour may not be what you want (see the next section). Warning: If the pattern uses the (?| feature to set up multiple subpat- terns with the same number, as described in the section on duplicate subpattern numbers in the pcrepattern page, you cannot use names to distinguish the different subpatterns, because names are not included in the compiled code. The matching process uses only numbers. For this reason, the use of different names for subpatterns of the same number causes an error at compile time. 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. (Duplicate names are always allowed for subpatterns with the same number, created by using the (?| feature. Indeed, if such subpatterns are named, they are required to use the same names.) 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 documentation. 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, PCRE_ERROR_NOSUBSTRING (-7) is returned; no data is returned. The pcre_get_stringnumber() function returns one of the numbers 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 (-7) if there are none. The format of the table is described above in the sec- tion entitled Information about a pattern above. Given all the rele- vant entries for the name, you can extract each of their numbers, and hence the captured data, if any. FINDING ALL POSSIBLE MATCHES 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 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 matches, pcre_exec() will yield PCRE_ERROR_NOMATCH. OBTAINING AN ESTIMATE OF STACK USAGE Matching certain patterns using pcre_exec() can use a lot of process stack, which in certain environments can be rather limited in size. Some users find it helpful to have an estimate of the amount of stack that is used by pcre_exec(), to help them set recursion limits, as described in the pcrestack documentation. The estimate that is output by pcretest when called with the -m and -C options is obtained by call- ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its first five arguments. Normally, if its first argument is NULL, pcre_exec() immediately returns the negative error code PCRE_ERROR_NULL, but with this special combination of arguments, it returns instead a negative number whose absolute value is the approximate stack frame size in bytes. (A nega- tive number is used so that it is clear that no match has happened.) The value is approximate because in some cases, recursive calls to pcre_exec() occur when there are one or two additional variables on the stack. If PCRE has been compiled to use the heap instead of the stack for recursion, the value returned is the size of each block that is obtained from the heap. MATCHING A PATTERN: THE ALTERNATIVE FUNCTION int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, 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 matching algorithm that scans the subject string just once, and does not backtrack. This has different characteristics to the normal algorithm, and is not compatible with Perl. Some of the features of PCRE patterns are not supported. Never- theless, there are times when this kind of matching can be useful. For a discussion of the two matching algorithms, and a list of features that pcre_dfa_exec() does not support, see the pcrematching documenta- tion. 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 repeated here. 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 potential matches. Here is an example of a simple call to pcre_dfa_exec(): int rc; int ovector[10]; int wspace[20]; rc = pcre_dfa_exec( re, /* result of pcre_compile() */ NULL, /* we didn't study the pattern */ "some string", /* the subject string */ 11, /* the length of the subject string */ 0, /* start at offset 0 in the subject */ 0, /* default options */ ovector, /* vector of integers for substring information */ 10, /* number of elements (NOT size in bytes) */ wspace, /* working space vector */ 20); /* number of elements (NOT size in bytes) */ 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_NEW- LINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last four of these are exactly the same as for pcre_exec(), so their description is not repeated here. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT These have the same general effect as they do for pcre_exec(), but the details are slightly different. When PCRE_PARTIAL_HARD is set for pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- ject is reached and there is still at least one matching possibility that requires additional characters. This happens even if some complete matches have also been found. When PCRE_PARTIAL_SOFT is set, 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 possibility. The portion of the string that was inspected when the longest partial match was found is set as the first matching string in both cases. There is a more detailed discussion of partial and multi-segment matching, with exam- ples, in the pcrepartial documentation. 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 alterna- tive 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() returns a partial match, it is possible to call it again, with additional 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- 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, if the pattern <.*> is matched against the string This is no more the three matched strings are 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. In fact, 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 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 filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec() can use the entire ovector for returning matched strings. 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 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 reference. PCRE_ERROR_DFA_UCOND (-17) This return is given if pcre_dfa_exec() encounters a condition item that uses a back reference for the condition, or a test for recursion in a specific group. These are not supported. PCRE_ERROR_DFA_UMLIMIT (-18) This return is given if pcre_dfa_exec() is called with an extra block that contains a setting of the match_limit or match_limit_recursion fields. This is not supported (these fields are meaningless for DFA matching). PCRE_ERROR_DFA_WSSIZE (-19) 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 should be extremely rare, as a vector of size 1000 is used. PCRE_ERROR_DFA_BADRESTART (-30) When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some plausibility checks are made on the contents of the workspace, which should contain data about the previous partial match. If any of these checks fail, this error is given. SEE ALSO pcre16(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematch- ing(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcresample(3), pcrestack(3). AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 17 June 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCRECALLOUT(3) PCRECALLOUT(3) NAME PCRE - Perl-compatible regular expressions PCRE CALLOUTS int (*pcre_callout)(pcre_callout_block *); int (*pcre16_callout)(pcre16_callout_block *); PCRE provides a feature called "callout", which is a means of temporar- ily passing control to the caller of PCRE in the middle of pattern matching. The caller of PCRE provides an external function by putting its entry point in the global variable pcre_callout (pcre16_callout for the 16-bit library). 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. Different callout points can be identified by putting 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 option bit is set when a pattern is compiled, PCRE automatically inserts callouts, all with number 255, before each item in the pattern. For example, if PCRE_AUTO_CALLOUT is used with the pattern A(\d{2}|--) it is processed as if it were (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) Notice that there is a callout before and after each parenthesis and alternation bar. Automatic callouts can be used for tracking the progress of pattern matching. The pcretest command has an option that sets automatic callouts; when it is used, the output indicates how the pattern is matched. This is useful information when you are trying to optimize the performance of a particular pattern. The use of callouts in a pattern makes it ineligible for optimization by the just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE option always fails. MISSING CALLOUTS You should be aware that, because of optimizations in the way PCRE matches patterns by default, callouts sometimes do not happen. For example, if the pattern is ab(?C4)cd PCRE knows that any matching string must contain the letter "d". If the subject string is "abyz", the lack of "d" means that matching doesn't ever start, and the callout is never reached. However, with "abyd", though the result is still no match, the callout is obeyed. If the pattern is studied, PCRE knows the minimum length of a matching string, and will immediately give a "no match" return without actually running a match if the subject is not long enough, or, for unanchored patterns, if it has been scanned far enough. You can disable these optimizations by passing the PCRE_NO_START_OPTI- MIZE option to the matching function, or by starting the pattern with (*NO_START_OPT). This slows down the matching process, but does ensure that callouts such as the example above are obeyed. THE CALLOUT INTERFACE During matching, when PCRE reaches a callout point, the external func- tion defined by pcre_callout or pcre16_callout is called (if it is set). This applies to both normal and DFA matching. The only argument to the callout function is a pointer to a pcre_callout or pcre16_call- out block. These structures contains the following fields: int version; int callout_number; int *offset_vector; const char *subject; (8-bit version) PCRE_SPTR16 subject; (16-bit version) int subject_length; int start_match; int current_position; int capture_top; int capture_last; void *callout_data; int pattern_position; int next_item_length; const unsigned char *mark; (8-bit version) const PCRE_UCHAR16 *mark; (16-bit version) The version field is an integer containing the version number of the block format. The initial version was 0; the current version is 2. The version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields. The callout_number field contains the number of the callout, as com- piled into the pattern (that is, the number after ?C for manual call- outs, and 255 for automatically generated callouts). The offset_vector field is a pointer to the vector of offsets that was passed by the caller to the matching function. When pcre_exec() or pcre16_exec() is used, the contents can be inspected, in order to extract substrings that have been matched so far, in the same way as for extracting substrings after a match has completed. For the DFA matching functions, this field is not useful. The subject and subject_length fields contain copies of the values that were passed to the matching function. The start_match field normally contains the offset within the subject at which the current match attempt started. However, if the escape sequence \K has been encountered, this value is changed to reflect the modified starting point. If the pattern is not anchored, the callout function may be called several times from the same point in the pattern for different starting points in the subject. The current_position field contains the offset within the subject of the current match pointer. When the pcre_exec() or pcre16_exec() is used, the capture_top field contains one more than the number of the highest numbered captured sub- string so far. If no substrings have been captured, the value of cap- ture_top is one. This is always the case when the DFA functions are used, because they do not support captured substrings. The capture_last field contains the number of the most recently cap- tured substring. If no substrings have been captured, its value is -1. This is always the case for the DFA matching functions. The callout_data field contains a value that is passed to a matching function specifically so that it can be passed back in callouts. It is passed in the callout_data field of a pcre_extra or pcre16_extra data structure. If no such data was passed, the value of callout_data in a callout block is NULL. There is a description of the pcre_extra struc- ture in the pcreapi documentation. The pattern_position field is present from version 1 of the callout structure. It contains the offset to the next item to be matched in the pattern string. The next_item_length field is present from version 1 of the callout structure. It contains the length of the next item to be matched in the pattern string. When the callout immediately precedes an alternation bar, a closing parenthesis, or the end of the pattern, the length is zero. When the callout precedes an opening parenthesis, the length is that of the entire subpattern. The pattern_position and next_item_length fields are intended to help in distinguishing between different automatic callouts, which all have the same callout number. However, they are set for all callouts. The mark field is present from version 2 of the callout structure. In callouts from pcre_exec() or pcre16_exec() it contains a pointer to the zero-terminated name of the most recently passed (*MARK), (*PRUNE), or (*THEN) item in the match, or NULL if no such items have been passed. Instances of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In callouts from the DFA matching functions this field always contains NULL. RETURN VALUES The external callout function returns an integer to PCRE. If the value is zero, matching proceeds as normal. If the value is greater than zero, matching fails at the current point, but the testing of other matching possibilities goes ahead, just as if a lookahead assertion had failed. If the value is less than zero, the match is abandoned, the matching function returns the negative value. Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a stan- dard "no match" failure. The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions; it will never be used by PCRE itself. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 08 Janurary 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCRECOMPAT(3) PCRECOMPAT(3) NAME PCRE - Perl-compatible regular expressions DIFFERENCES BETWEEN PCRE AND PERL This document describes the differences in the ways that PCRE and Perl handle regular expressions. The differences described here are with respect to Perl versions 5.10 and above. 1. PCRE has only a subset of Perl's Unicode support. Details of what it does have are given in the pcreunicode page. 2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do not mean what you might think. For example, (?!a){3} does not assert that the next three characters are not "a". It just asserts that the next character is not "a" three times (in principle: PCRE optimizes this to run the assertion just once). Perl allows repeat quantifiers on other assertions such as \b, but these do not seem to have any use. 3. Capturing subpatterns that occur inside negative lookahead asser- tions are counted, but their entries in the offsets vector are never set. Perl sets its numerical variables from any such patterns that are matched before the assertion fails to match something (thereby succeed- ing), but only if the negative lookahead assertion contains just one branch. 4. Though binary zero characters are supported in the subject string, they are not allowed in a pattern string because it is passed as a nor- mal C string, terminated by zero. The escape sequence \0 can be used in the pattern to represent a binary zero. 5. The following Perl escape sequences are not supported: \l, \u, \L, \U, and \N when followed by a character name or Unicode value. (\N on its own, matching a non-newline character, is supported.) In fact these are implemented by Perl's general string-handling and are not part of its pattern matching engine. If any of these are encountered by PCRE, an error is generated by default. However, if the PCRE_JAVASCRIPT_COM- PAT option is set, \U and \u are interpreted as JavaScript interprets them. 6. The Perl escape sequences \p, \P, and \X are supported only if PCRE is built with Unicode character property support. The properties that can be tested with \p and \P are limited to the general category prop- erties such as Lu and Nd, script names such as Greek or Han, and the derived properties Any and L&. PCRE does support the Cs (surrogate) property, which Perl does not; the Perl documentation says "Because Perl hides the need for the user to understand the internal representa- tion of Unicode characters, there is no need to implement the somewhat messy concept of surrogates." 7. PCRE implements a simpler version of \X than Perl, which changed to make \X match what Unicode calls an "extended grapheme cluster". This is more complicated than an extended Unicode sequence, which is what PCRE matches. 8. PCRE does support the \Q...\E escape for quoting substrings. Charac- ters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they cause variable interpolation (but of course PCRE does not have variables). Note the following examples: Pattern PCRE matches Perl matches \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz \Qabc\$xyz\E abc\$xyz abc\$xyz \Qabc\E\$\Qxyz\E abc$xyz abc$xyz The \Q...\E sequence is recognized both inside and outside character classes. 9. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) constructions. However, there is support for recursive patterns. This is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout" feature allows an external function to be called during pat- tern matching. See the pcrecallout documentation for details. 10. Subpatterns that are called as subroutines (whether or not recur- sively) are always treated as atomic groups in PCRE. This is like Python, but unlike Perl. Captured values that are set outside a sub- routine call can be reference from inside in PCRE, but not in Perl. There is a discussion that explains these differences in more detail in the section on recursion differences from Perl in the pcrepattern page. 11. If any of the backtracking control verbs are used in an assertion or in a subpattern that is called as a subroutine (whether or not recursively), their effect is confined to that subpattern; it does not extend to the surrounding pattern. This is not always the case in Perl. In particular, if (*THEN) is present in a group that is called as a subroutine, its action is limited to that group, even if the group does not contain any | characters. There is one exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a success- ful positive assertion is passed back when a match succeeds (compare capturing parentheses in assertions). Note that such subpatterns are processed as anchored at the point where they are tested. 12. There are some differences that are concerned with the settings of captured strings when part of a pattern is repeated. For example, matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b". 13. PCRE's handling of duplicate subpattern numbers and duplicate sub- pattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external ta- ble to translate between numbers and names. In particular, a pattern such as (?|(?A)|(? (Oniguruma syntax) are not synonymous. The former is a back reference; the latter is a subroutine call. Generic character types Another use of backslash is for specifying generic character types: \d any decimal digit \D any character that is not a decimal digit \h any horizontal white space character \H any character that is not a horizontal white space character \s any white space character \S any character that is not a white space character \v any vertical white space character \V any character that is not a vertical white space character \w any "word" character \W any "non-word" character There is also the single sequence \N, which matches a non-newline char- acter. This is the same as the "." metacharacter when PCRE_DOTALL is not set. Perl also uses \N to match characters by name; PCRE does not support this. Each pair of lower and upper case escape sequences partitions the com- plete set of characters into two disjoint sets. Any given character matches one, and only one, of each pair. The sequences can appear both inside and outside character classes. They each match one character of the appropriate type. If the current matching point is at the end of the subject string, all of them fail, because there is no character to match. 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). 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 that is a letter or digit. By default, the definition of letters and digits is con- trolled by PCRE's low-valued character tables, and may vary if locale- specific matching is taking place (see "Locale support" in the pcreapi page). For example, in a French locale such as "fr_FR" in Unix-like systems, or "french" in Windows, some character codes greater than 128 are used for accented letters, and these are then matched by \w. The use of locales with Unicode is discouraged. By default, in a UTF mode, characters with values greater than 128 never match \d, \s, or \w, and always match \D, \S, and \W. These sequences retain their original meanings from before UTF support was available, mainly for efficiency reasons. However, if PCRE is compiled with Unicode property support, and the PCRE_UCP option is set, the be- haviour is changed so that Unicode properties are used to determine character types, as follows: \d any character that \p{Nd} matches (decimal digit) \s any character that \p{Z} matches, plus HT, LF, FF, CR \w any character that \p{L} or \p{N} matches, plus underscore The upper case escapes match the inverse sets of characters. Note that \d matches only decimal digits, whereas \w matches any Unicode digit, as well as any Unicode letter, and underscore. Note also that PCRE_UCP affects \b, and \B because they are defined in terms of \w and \W. Matching these sequences is noticeably slower when PCRE_UCP is set. The sequences \h, \H, \v, and \V are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII characters by default, these always match certain high-valued codepoints, whether or not PCRE_UCP is set. The horizontal space char- acters are: U+0009 Horizontal tab U+0020 Space U+00A0 Non-break space U+1680 Ogham space mark U+180E Mongolian vowel separator U+2000 En quad U+2001 Em quad U+2002 En space U+2003 Em space U+2004 Three-per-em space U+2005 Four-per-em space U+2006 Six-per-em space U+2007 Figure space U+2008 Punctuation space U+2009 Thin space U+200A Hair space U+202F Narrow no-break space U+205F Medium mathematical space U+3000 Ideographic space The vertical space characters are: U+000A Linefeed U+000B Vertical tab U+000C Form feed U+000D Carriage return U+0085 Next line U+2028 Line separator U+2029 Paragraph separator In 8-bit, non-UTF-8 mode, only the characters with codepoints less than 256 are relevant. Newline sequences Outside a character class, by default, the escape sequence \R matches any Unicode newline sequence. In 8-bit non-UTF-8 mode \R is equivalent to the following: (?>\r\n|\n|\x0b|\f|\r|\x85) This is an example of an "atomic group", details of which are given below. This particular group matches either the two-character sequence CR followed by LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab, U+000B), FF (form feed, U+000C), CR (car- riage return, U+000D), or NEL (next line, U+0085). The two-character sequence is treated as a single unit that cannot be split. In other modes, two additional characters whose codepoints are greater than 255 are added: LS (line separator, U+2028) and PS (paragraph sepa- rator, U+2029). Unicode character property support is not needed for these characters to be recognized. It is possible to restrict \R to match only CR, LF, or CRLF (instead of the complete set of Unicode line endings) by setting the option PCRE_BSR_ANYCRLF either at compile time or when the pattern is matched. (BSR is an abbrevation for "backslash R".) This can be made the default when PCRE is built; if this is the case, the other behaviour can be requested via the PCRE_BSR_UNICODE option. It is also possible to specify these settings by starting a pattern string with one of the following sequences: (*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence These override the default and the options given to the compiling func- tion, but they can themselves be overridden by options given to a matching function. Note that these special settings, which are not Perl-compatible, are recognized only at the very start of a pattern, and that they must be in upper case. If more than one of them is present, the last one is used. They can be combined with a change of newline convention; for example, a pattern can start with: (*ANY)(*BSR_ANYCRLF) They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special sequences. Inside a character class, \R is treated as an unrecognized escape sequence, and so matches the letter "R" by default, but causes an error if PCRE_EXTRA is set. Unicode character properties When PCRE is built with Unicode character property support, three addi- tional escape sequences that match characters with specific properties are available. When in 8-bit non-UTF-8 mode, these sequences are of course limited to testing characters whose codepoints are less than 256, but they do work in this mode. The extra escape sequences are: \p{xx} a character with the xx property \P{xx} a character without the xx property \X an extended Unicode sequence The property names represented by xx above are limited to the Unicode script names, the general category properties, "Any", which matches any character (including newline), and some special PCRE properties (described in the next section). Other Perl properties such as "InMu- sicalSymbols" are not currently supported by PCRE. Note that \P{Any} does not match any characters, so always causes a match failure. Sets of Unicode characters are defined as belonging to certain scripts. A character from one of these sets can be matched using a script name. For example: \p{Greek} \P{Han} Those that are not part of an identified script are lumped together as "Common". The current list of scripts is: Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi. Each character has exactly one Unicode general category property, spec- ified by a two-letter abbreviation. For compatibility with Perl, nega- tion can be specified by including a circumflex between the opening brace and the property name. For example, \p{^Lu} is the same as \P{Lu}. If only one letter is specified with \p or \P, it includes all the gen- eral category properties that start with that letter. In this case, in the absence of negation, the curly brackets in the escape sequence are optional; these two examples have the same effect: \p{L} \pL The following general category property codes are supported: C Other Cc Control Cf Format Cn Unassigned Co Private use Cs Surrogate L Letter Ll Lower case letter Lm Modifier letter Lo Other letter Lt Title case letter Lu Upper case letter M Mark Mc Spacing mark Me Enclosing mark Mn Non-spacing mark N Number Nd Decimal number Nl Letter number No Other number P Punctuation Pc Connector punctuation Pd Dash punctuation Pe Close punctuation Pf Final punctuation Pi Initial punctuation Po Other punctuation Ps Open punctuation S Symbol Sc Currency symbol Sk Modifier symbol Sm Mathematical symbol So Other symbol Z Separator Zl Line separator Zp Paragraph separator Zs Space separator The special property L& is also supported: it matches a character that has the Lu, Ll, or Lt property, in other words, a letter that is not classified as a modifier or "other". The Cs (Surrogate) property applies only to characters in the range U+D800 to U+DFFF. Such characters are not valid in Unicode strings and so cannot be tested by PCRE, unless UTF validity checking has been turned off (see the discussion of PCRE_NO_UTF8_CHECK and PCRE_NO_UTF16_CHECK in the pcreapi page). Perl does not support the Cs property. The long synonyms for property names that Perl supports (such as \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- erty. Instead, this property is assumed for any code point that is not in the Unicode table. Specifying caseless matching does not affect these escape sequences. For example, \p{Lu} always matches only upper case letters. The \X escape matches any number of Unicode characters that form an extended Unicode sequence. \X is equivalent to (?>\PM\pM*) That is, it matches a character without the "mark" property, followed by zero or more characters with the "mark" property, and treats the sequence as an atomic group (see below). Characters with the "mark" property are typically accents that affect the preceding character. None of them have codepoints less than 256, so in 8-bit non-UTF-8 mode \X matches any one character. Note that recent versions of Perl have changed \X to match what Unicode calls an "extended grapheme cluster", which has a more complicated def- inition. Matching characters by Unicode property is not fast, because PCRE has to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \d and \w do not use Unicode properties in PCRE by default, though you can make them do so by setting the PCRE_UCP option or by starting the pat- tern with (*UCP). PCRE's additional properties As well as the standard Unicode properties described in the previous section, PCRE supports four more that make it possible to convert tra- ditional escape sequences such as \w and \s and POSIX character classes to use Unicode properties. PCRE uses these non-standard, non-Perl prop- erties internally when PCRE_UCP is set. They are: Xan Any alphanumeric character Xps Any POSIX space character Xsp Any Perl space character Xwd Any Perl "word" character Xan matches characters that have either the L (letter) or the N (num- ber) property. Xps matches the characters tab, linefeed, vertical tab, form feed, or carriage return, and any other character that has the Z (separator) property. Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the same characters as Xan, plus underscore. Resetting the match start The escape sequence \K causes any previously matched characters not to be included in the final matched sequence. For example, the pattern: foo\Kbar matches "foobar", but reports that it has matched "bar". This feature is similar to a lookbehind assertion (described below). However, in this case, the part of the subject before the real match does not have to be of fixed length, as lookbehind assertions do. The use of \K does not interfere with the setting of captured substrings. For example, when the pattern (foo)\Kbar matches "foobar", the first substring is still set to "foo". Perl documents that the use of \K within assertions is "not well defined". In PCRE, \K is acted upon when it occurs inside positive assertions, but is ignored in negative assertions. Simple assertions The final use of backslash is for certain simple assertions. An asser- tion specifies a condition that has to be met at a particular point in a match, without consuming any characters from the subject string. The use of subpatterns for more complicated assertions is described below. The backslashed assertions are: \b matches at a word boundary \B matches when not at a word boundary \A matches at the start of the subject \Z matches at the end of the subject also matches before a newline at the end of the subject \z matches only at the end of the subject \G matches at the first matching position in the subject Inside a character class, \b has a different meaning; it matches the backspace character. If any other of these assertions appears in a character class, by default it matches the corresponding literal char- acter (for example, \B matches the letter B). However, if the PCRE_EXTRA option is set, an "invalid escape sequence" error is gener- ated instead. A word boundary is a position in the subject string where the current character and the previous character do not both match \w or \W (i.e. one matches \w and the other matches \W), or the start or end of the string if the first or last character matches \w, respectively. In a UTF mode, the meanings of \w and \W can be changed by setting the PCRE_UCP option. When this is done, it also affects \b and \B. Neither PCRE nor Perl has a separate "start of word" or "end of word" metase- quence. However, whatever follows \b normally determines which it is. For example, the fragment \ba matches "a" at the start of a word. The \A, \Z, and \z assertions differ from the traditional circumflex and dollar (described in the next section) in that they only ever match at the very start and end of the subject string, whatever options are set. Thus, they are independent of multiline mode. These three asser- tions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which affect only the behaviour of the circumflex and dollar metacharacters. 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 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 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 at a time, it cannot reproduce this behaviour. 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. 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 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 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 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, 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) AND \N Outside a character class, a dot in the pattern matches any one charac- ter in the subject string except (by default) a character that signi- fies the end of a line. When a line ending is defined as a single character, dot never matches that character; when the two-character sequence CRLF is used, dot does not match CR if it is immediately followed by LF, but otherwise it matches all characters (including isolated CRs and LFs). When any Uni- code line endings are being recognized, dot does not match CR or LF or any of the other line ending characters. 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 the two-character sequence CRLF is present in the subject string, 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. The escape sequence \N behaves like a dot, except that it is not affected by the PCRE_DOTALL option. In other words, it matches any character except one that signifies the end of a line. Perl also uses \N to match characters by name; PCRE does not support this. MATCHING A SINGLE DATA UNIT Outside a character class, the escape sequence \C matches any one data unit, whether or not a UTF mode is set. In the 8-bit library, one data unit is one byte; in the 16-bit library it is a 16-bit unit. Unlike a dot, \C always matches line-ending characters. The feature is provided in Perl in order to match individual bytes in UTF-8 mode, but it is unclear how it can usefully be used. Because \C breaks up characters into individual data units, matching one unit with \C in a UTF mode means that the rest of the string may start with a malformed UTF char- acter. This has undefined results, because PCRE assumes that it is dealing with valid UTF strings (and by default it checks this at the start of processing unless the PCRE_NO_UTF8_CHECK or PCRE_NO_UTF16_CHECK option is used). PCRE does not allow \C to appear in lookbehind assertions (described below) in a UTF mode, because this would make it impossible to calcu- late the length of the lookbehind. In general, the \C escape sequence is best avoided. However, one way of using it that avoids the problem of malformed UTF characters is to use a lookahead to check the length of the next character, as in this pat- tern, which could be used with a UTF-8 string (ignore white space and line breaks): (?| (?=[\x00-\x7f])(\C) | (?=[\x80-\x{7ff}])(\C)(\C) | (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) | (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C)) A group that starts with (?| resets the capturing parentheses numbers in each alternative (see "Duplicate Subpattern Numbers" below). The assertions at the start of each branch check the next UTF-8 character for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The character's individual bytes are then captured by the appropriate num- ber of groups. SQUARE BRACKETS AND CHARACTER CLASSES An opening square bracket introduces a character class, terminated by a closing square bracket. A closing square bracket on its own is not spe- cial by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, a lone closing square bracket causes a compile-time error. If a closing square bracket is required as a member of the class, it should be the first data character in the class (after an initial circumflex, if present) or escaped with a backslash. A character class matches a single character in the subject. In a UTF mode, the character may be more than one data unit long. A matched character must be in the set of characters defined by the class, unless the first character in the class definition is a circumflex, in which case the subject character must not be in the set defined by the class. If a circumflex is actually required as a member of the class, ensure it is not the first character, or escape it with a backslash. For example, the character class [aeiou] matches any lower case vowel, while [^aeiou] matches any character that is not a lower case vowel. Note that a circumflex is just a convenient notation for specifying the characters that are in the class by enumerating those that are not. A class that starts with a circumflex is not an assertion; it still con- sumes a character from the subject string, and therefore it fails if the current pointer is at the end of the string. In UTF-8 (UTF-16) mode, characters with values greater than 255 (0xffff) can be included in a class as a literal string of data units, or by using the \x{ escaping mechanism. When caseless matching is set, any letters in a class represent both their upper case and lower case versions, so for example, a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a caseful version would. In a UTF 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 compiled with Unicode property support, but not otherwise. If you want to use caseless matching in a UTF mode for characters 128 and above, you must ensure that PCRE is compiled with Unicode property support as well as with UTF support. Characters that might indicate line breaks 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 between d and m, inclusive. If a minus character is required in a class, it must be escaped with a backslash or appear in a position where it cannot be interpreted as indicating a range, typically as the first or last character in the class. It is not possible to have the literal character "]" as the end charac- ter of a range. A pattern such as [W-]46] is interpreted as a class of two characters ("W" and "-") followed by a literal string "46]", so it would match "W46]" or "-46]". However, if the "]" is escaped with a backslash it is interpreted as the end of range, so [W-\]46] is inter- preted as a class containing a range followed by two other characters. The octal or hexadecimal representation of "]" can also be used to end a range. Ranges operate in the collating sequence of character values. They can also be used for characters specified numerically, for example [\000-\037]. Ranges can include any characters that are valid for the current mode. If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character tables for a French locale are in use, [\xc8-\xcb] matches accented E characters in both cases. In UTF modes, PCRE supports the concept of case for characters with values greater than 128 only when it is compiled with Unicode property support. The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V, \w, and \W may appear in a character class, and add the characters that they match to the class. For example, [\dABCDEF] matches any hexadeci- mal digit. In UTF modes, the PCRE_UCP option affects the meanings of \d, \s, \w and their upper case partners, just as it does when they appear outside a character class, as described in the section entitled "Generic character types" above. The escape sequence \b has a different meaning inside a character class; it matches the backspace character. The sequences \B, \N, \R, and \X are not special inside a character class. Like any other unrecognized escape sequences, they are treated as the literal characters "B", "N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is set. A circumflex can conveniently be used with the upper case character types to specify a more restricted set of characters than the matching lower case type. For example, the class [^\W_] matches any letter or digit, but not underscore, whereas [\w] includes underscore. A positive character class should be read as "something OR something OR ..." and a negative class as "NOT something AND NOT something AND NOT ...". The only metacharacters that are recognized in character classes are backslash, hyphen (only where it can be interpreted as specifying a range), circumflex (only at the start), opening square bracket (only when it can be interpreted as introducing a POSIX class name - see the next section), and the terminating closing square bracket. However, escaping other non-alphanumeric characters does no harm. POSIX CHARACTER CLASSES Perl supports the POSIX notation for character classes. This uses names enclosed by [: and :] within the enclosing square brackets. PCRE also supports this notation. For example, [01[:alpha:]%] matches "0", "1", any alphabetic character, or "%". The supported class names are: alnum letters and digits alpha letters ascii character codes 0 - 127 blank space or tab only cntrl control characters digit decimal digits (same as \d) graph printing characters, excluding space lower lower case letters print printing characters, including space punct printing characters, excluding letters and digits and space space white space (not quite the same as \s) upper upper case letters word "word" characters (same as \w) xdigit hexadecimal digits The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), and space (32). Notice that this list includes the VT character (code 11). This makes "space" different to \s, which does not include VT (for Perl compatibility). The name "word" is a Perl extension, and "blank" is a GNU extension from Perl 5.8. Another Perl extension is negation, which is indicated by a ^ character after the colon. For example, [12[:^digit:]] matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered. By default, in UTF modes, characters with values greater than 128 do not match any of the POSIX character classes. However, if the PCRE_UCP option is passed to pcre_compile(), some of the classes are changed so that Unicode character properties are used. This is achieved by replac- ing the POSIX classes by other sequences, as follows: [:alnum:] becomes \p{Xan} [:alpha:] becomes \p{L} [:blank:] becomes \h [:digit:] becomes \p{Nd} [:lower:] becomes \p{Ll} [:space:] becomes \p{Xps} [:upper:] becomes \p{Lu} [:word:] becomes \p{Xwd} Negated versions, such as [:^alpha:] use \P instead of \p. The other POSIX classes are unchanged, and match only characters with code points less than 128. VERTICAL BAR Vertical bar characters are used to separate alternative patterns. For example, the pattern gilbert|sullivan 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 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 The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and PCRE_EXTENDED options (which are Perl-compatible) can be changed from within the pattern by a sequence of Perl option letters enclosed between "(?" and ")". The option letters are i for PCRE_CASELESS m for PCRE_MULTILINE s for PCRE_DOTALL x for PCRE_EXTENDED For example, (?im) sets caseless, multiline matching. It is also possi- ble to unset these options by preceding the letter with a hyphen, and a combined setting and unsetting such as (?im-sx), which sets PCRE_CASE- LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, is also permitted. If a letter appears both before and after the hyphen, the option is unset. 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. When one of these option changes occurs at top level (that is, not inside subpattern parentheses), the change applies to the remainder of the pattern that follows. If the change is placed right at the start of a pattern, PCRE extracts it into the global options (and it will there- fore show up in data extracted by the pcre_fullinfo() function). An option change within a subpattern (see below for a description of subpatterns) affects only that part of the subpattern that follows it, so (a(?i)b)c matches abc and aBc and no other strings (assuming PCRE_CASELESS is not used). By this means, options can be made to have different settings in different parts of the pattern. Any changes made in one alternative do carry on into subsequent branches within the same subpattern. For example, (a(?i)b|c) matches "ab", "aB", "c", and "C", even though when matching "C" the first branch is abandoned before the option setting. This is because the effects of option settings happen at compile time. There would be some very weird behaviour otherwise. Note: There are other PCRE-specific options that can be set by the application when the compiling or matching functions are called. In some cases the pattern can contain special leading sequences such as (*CRLF) to override what the application has set or what has been defaulted. Details are given in the section entitled "Newline sequences" above. There are also the (*UTF8), (*UTF16), and (*UCP) leading sequences that can be used to set UTF and Unicode property modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, and the PCRE_UCP options, respectively. SUBPATTERNS Subpatterns are delimited by parentheses (round brackets), which can be nested. Turning part of a pattern into a subpattern does two things: 1. It localizes a set of alternatives. For example, the pattern cat(aract|erpillar|) matches "cataract", "caterpillar", or "cat". Without the parentheses, it would match "cataract", "erpillar" or an 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 string that matched the subpattern is passed back to the caller via the ovector argument of the matching function. (This applies only to the traditional matching functions; the DFA matching functions do not sup- port capturing.) 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 pattern the ((red|white) (king|queen)) 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 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. 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 "Saturday". DUPLICATE SUBPATTERN NUMBERS Perl 5.10 introduced a feature whereby each alternative in a subpattern uses the same numbers for its capturing parentheses. Such a subpattern starts with (?| and is itself a non-capturing subpattern. For example, consider this pattern: (?|(Sat)ur|(Sun))day Because the two alternatives are inside a (?| group, both sets of cap- turing parentheses are numbered one. Thus, when the pattern matches, you can look at captured substring number one, whichever alternative matched. This construct is useful when you want to capture part, but not all, of one of a number of alternatives. Inside a (?| group, paren- theses are numbered as usual, but the number is reset at the start of each branch. The numbers of any capturing parentheses that follow the subpattern start after the highest number used in any branch. The fol- lowing example is taken from the Perl documentation. The numbers under- neath show in which buffer the captured content will be stored. # before ---------------branch-reset----------- after / ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x # 1 2 2 3 2 3 4 A back reference to a numbered subpattern uses the most recent value that is set for that number by any subpattern. The following pattern matches "abcabc" or "defdef": /(?|(abc)|(def))\1/ In contrast, a subroutine call to a numbered subpattern always refers to the first one in the pattern with the given number. The following pattern matches "abcabc" or "defabc": /(?|(abc)|(def))(?1)/ If a condition test for a subpattern's having matched refers to a non- unique number, the test is true if any of the subpatterns of that num- ber have matched. An alternative approach to using this "branch reset" feature is to use duplicate named subpatterns, as described in the next section. 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. This feature was not added to Perl until release 5.10. Python had the feature earlier, and PCRE introduced it at release 4.0, using the Python syntax. PCRE now supports both the Perl and the Python syn- tax. Perl allows identically numbered subpatterns to have different names, but PCRE does not. In PCRE, a subpattern can be named in one of three ways: (?...) or (?'name'...) as in Perl, or (?P...) as in Python. References to capturing parentheses from other parts of the pattern, such as back references, recursion, and conditions, 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, exactly as if the names were not present. The PCRE API provides function calls for extracting the name-to-number translation table from a compiled pattern. There is also a convenience 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. (Duplicate names are also always permitted for subpatterns with the same number, set up as described in the previous section.) Dupli- cate names 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: (?Mon|Fri|Sun)(?:day)?| (?Tue)(?:sday)?| (?Wed)(?:nesday)?| (?Thu)(?:rsday)?| (?Sat)(?:urday)? There are five capturing substrings, but only one is ever set after a match. (An alternative way of solving this problem is to use a "branch reset" subpattern, as described in the previous section.) 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 back reference to a non-unique named subpattern from elsewhere in the pattern, the one that corresponds to the first occur- rence of the name is used. In the absence of duplicate numbers (see the previous section) this is the one with the lowest number. If you use a named reference in a condition test (see the section about conditions below), either to check whether a subpattern has matched, or to check for recursion, all subpatterns with the same name are tested. If the condition is true for any one of them, the overall condition is true. This is the same behaviour as testing by number. For further details of the interfaces for handling named subpatterns, see the pcreapi documen- tation. Warning: You cannot use different names to distinguish between two sub- patterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if differ- ent names are given to subpatterns with the same number. However, you can give the same name to subpatterns with the same number, even when PCRE_DUPNAMES is not set. REPETITION Repetition is specified by quantifiers, which can follow any of the following items: a literal data character the dot metacharacter the \C escape sequence the \X escape sequence the \R escape sequence an escape such as \d or \pL that matches a single character a character class a back reference (see next section) a parenthesized subpattern (including assertions) a subroutine call to a subpattern (recursive or otherwise) The general repetition quantifier specifies a minimum and maximum num- ber of permitted matches, by giving the two numbers in curly brackets (braces), separated by a comma. The numbers must be less than 65536, and the first must be less than or equal to the second. For example: z{2,4} matches "zz", "zzz", or "zzzz". A closing brace on its own is not a special character. If the second number is omitted, but the comma is present, there is no upper limit; if the second number and the comma are both omitted, the quantifier specifies an exact number of required matches. Thus [aeiou]{3,} matches at least 3 successive vowels, but may match many more, while \d{8} matches exactly 8 digits. An opening curly bracket that appears in a position where a quantifier is not allowed, or one that does not match the syntax of a quantifier, is taken as a literal character. For exam- ple, {,6} is not a quantifier, but a literal string of four characters. In UTF modes, quantifiers apply to characters rather than to individual data units. Thus, for example, \x{100}{2} matches two characters, each of which is represented by a two-byte sequence in a UTF-8 string. Simi- larly, \X{3} matches three Unicode extended sequences, each of which may be several data units long (and they may be of different lengths). The quantifier {0} is permitted, causing the expression to behave as if the previous item and the quantifier were not present. This may be use- ful for subpatterns that are referenced as subroutines from elsewhere in the pattern (but see also the section entitled "Defining subpatterns for use by reference only" below). Items other than subpatterns that have a {0} quantifier are omitted from the compiled pattern. For convenience, the three most common quantifiers have single-charac- ter abbreviations: * is equivalent to {0,} + is equivalent to {1,} ? is equivalent to {0,1} It is possible to construct infinite loops by following a subpattern that can match no characters with a quantifier that has no upper limit, for example: (a?)* Earlier versions of Perl and PCRE used to give an error at compile time for such patterns. However, because there are cases where this can be useful, such patterns are now accepted, but if any repetition of the subpattern does in fact match no characters, the loop is forcibly bro- ken. By default, the quantifiers are "greedy", that is, they match as much as possible (up to the maximum number of permitted times), without causing the rest of the pattern to fail. The classic example of where this gives problems is in trying to match comments in C programs. These appear between /* and */ and within the comment, individual * and / characters may appear. An attempt to match C comments by applying the pattern /\*.*\*/ to the string /* first comment */ not comment /* second comment */ fails, because it matches the entire string owing to the greediness of the .* item. 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 /\*.*?\*/ does the right thing with the C comments. The meaning of the various quantifiers is not otherwise changed, just the preferred number of matches. Do not confuse this use of question mark with its use as a quantifier in its own right. Because it has two uses, it can sometimes appear doubled, as in \d??\d 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 that 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. When a parenthesized subpattern is quantified with a minimum repeat count that is greater than 1 or with a limited maximum, more memory is required for the compiled pattern, in proportion to the size of the minimum or maximum. If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equiv- alent to Perl's /s) is set, thus allowing the dot 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 normally treats such a pattern as though it were preceded by \A. In cases where it is known that the subject string contains no new- lines, it is worth setting PCRE_DOTALL in order to obtain this opti- mization, or alternatively using ^ to indicate anchoring explicitly. However, there is one situation where the optimization cannot be used. When .* is inside capturing parentheses that are the subject of a back reference elsewhere in the pattern, a match at the start may fail where a later one succeeds. Consider, for example: (.*)abc\1 If the subject is "xyz123abc123" the match point is the fourth charac- ter. For this reason, such a pattern is not implicitly anchored. When a capturing subpattern is repeated, the value captured is the sub- string that matched the final iteration. For example, after (tweedle[dume]{3}\s*)+ has matched "tweedledum tweedledee" the value of the captured substring is "tweedledee". However, if there are nested capturing subpatterns, the corresponding captured values may have been set in previous itera- tions. For example, after /(a|(b))+/ matches "aba" the value of the second captured substring is "b". ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") repetition, failure of what follows normally causes the repeated item to be re-evaluated to see if a different number of repeats allows the rest of the pattern to match. Sometimes it is useful to prevent this, either to change the nature of the match, or to cause it fail earlier than it otherwise might, when the author of the pattern knows there is no point in carrying on. Consider, for example, the pattern \d+foo when applied to the subject line 123456bar After matching all 6 digits and then failing to match "foo", the normal action of the matcher is to try again with only 5 digits matching the \d+ item, and then with 4, and so on, before ultimately failing. "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides the means for specifying that once a subpattern has matched, it is not to be re-evaluated in this way. If we use atomic grouping for the previous example, the matcher gives up immediately on failing to match "foo" the first time. The notation is a kind of special parenthesis, starting with (?> as in this example: (?>\d+)foo This kind of parenthesis "locks up" the part of the pattern it con- tains once it has matched, and a failure further into the pattern is prevented from backtracking into it. Backtracking past it to previous items, however, works as normal. An alternative description is that a subpattern of this type matches the string of characters that an identical standalone pattern would match, if anchored at the current point in the subject string. Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as the above example can be thought of as a maximizing repeat that must swallow everything it can. So, while both \d+ and \d+? are pre- pared to adjust the number of digits they match in order to make the rest of the pattern match, (?>\d+) can only match an entire sequence of digits. Atomic groups in general can of course contain arbitrarily complicated subpatterns, and can be nested. However, when the subpattern for an atomic group is just a single repeated item, as in the example above, a simpler notation, called a "possessive quantifier" can be used. This consists of an additional + character following a quantifier. Using this notation, the previous example can be rewritten as \d++foo Note that a possessive quantifier can be used with an entire group, for example: (abc|xyz){2,3}+ Possessive quantifiers are always greedy; the setting of the PCRE_UNGREEDY option is ignored. They are a convenient notation for the simpler forms of atomic group. However, there is no difference in the meaning of a possessive quantifier and the equivalent atomic group, though there may be a performance difference; possessive quantifiers should be slightly faster. The possessive quantifier syntax is an extension to the Perl 5.8 syn- tax. 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. It ultimately found its way into Perl at release 5.10. PCRE has an optimization that automatically "possessifies" certain sim- ple pattern constructs. For example, the sequence A+B is treated as A++B because there is no point in backtracking into a sequence of A's when B must follow. When a pattern contains an unlimited repeat inside a subpattern that can itself be repeated an unlimited number of times, the use of an atomic group is the only way to avoid some failing matches taking a very long time indeed. The pattern (\D+|<\d+>)*[!?] matches an unlimited number of substrings that either consist of non- digits, or digits enclosed in <>, followed by either ! or ?. When it matches, it runs quickly. However, if it is applied to aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa it takes a long time before reporting failure. This is because the string can be divided between the internal \D+ repeat and the external * repeat in a large number of ways, and all have to be tried. (The example uses [!?] rather than a single character at the end, because both PCRE and Perl have an optimization that allows for fast failure when a single character is used. They remember the last single charac- ter that is required for a match, and fail early if it is not present in the string.) If the pattern is changed so that it uses an atomic group, like this: ((?>\D+)|<\d+>)*[!?] sequences of non-digits cannot be broken, and failure happens quickly. BACK REFERENCES Outside a character class, a backslash followed by a digit greater than 0 (and possibly further digits) is a back reference to a capturing sub- pattern earlier (that is, to its left) in the pattern, provided there have been that many previous capturing left parentheses. However, if the decimal number following the backslash is less than 10, 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. 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 a subpattern whose number is 10 or more using this syntax because a sequence such as \50 is interpreted as a character defined in octal. See the subsection entitled "Non-printing characters" above for further details of the handling of digits following a backslash. There is no such problem when named parentheses are used. A back reference to any subpattern is possible using named parentheses (see below). Another way of avoiding the ambiguity inherent in the use of digits following a backslash is to use the \g escape sequence. This escape must be followed by an unsigned number or a negative number, optionally enclosed in braces. These examples are all identical: (ring), \1 (ring), \g1 (ring), \g{1} An unsigned number specifies an absolute reference without the ambigu- ity that is present in the older syntax. It is also useful when literal digits follow the reference. A negative number is a relative reference. Consider this example: (abc(def)ghi)\g{-1} The sequence \g{-1} is a reference to the most recently started captur- ing subpattern before \g, that is, is it equivalent to \2 in this exam- ple. Similarly, \g{-2} would be equivalent to \1. The use of relative references can be helpful in long patterns, and also in patterns that are created by joining together fragments that contain references within themselves. 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- ple, ((?i)rah)\s+\1 matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original capturing subpattern is matched caselessly. There are several different ways of writing back references to named subpatterns. The .NET syntax \k{name} and the Perl syntax \k or \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified back reference syntax, in which \g can be used for both numeric and named references, is also supported. We could rewrite the above example in any of the following ways: (?(?i)rah)\s+\k (?'p1'(?i)rah)\s+\k{p1} (?P(?i)rah)\s+(?P=p1) (?(?i)rah)\s+\g{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 references to it always fail by default. For example, the pattern (a|(bc))\2 always fails if it starts to match "a" rather than "bc". However, if the PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back refer- ence to an unset value matches an empty string. Because there may be many capturing parentheses in a pattern, all dig- its following a backslash are taken as part of a potential back refer- ence number. If the pattern continues with a digit character, some delimiter must be used to terminate the back reference. If the PCRE_EXTENDED option is set, this can be white space. Otherwise, the \g{ syntax or an empty comment (see "Comments" below) can be used. Recursive back references 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. However, such references can be useful inside repeated sub- patterns. For example, the pattern (a|b\1)+ matches any number of "a"s and also "aba", "ababbaa" etc. At each iter- ation of the subpattern, the back reference matches the character string corresponding to the previous iteration. In order for this to work, the pattern must be such that the first iteration does not need to match the back reference. This can be done using alternation, as in the example above, or by a quantifier with a minimum of zero. Back references of this type cause the group that they reference to be treated as an atomic group. Once the whole group has been matched, a subsequent matching failure cannot cause backtracking into the middle of the group. ASSERTIONS An assertion is a test on the characters following or preceding the current matching point that does not actually consume any characters. The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are described above. More complicated assertions are coded as subpatterns. There are two kinds: those that look ahead of the current position in the subject string, and those that look behind it. An assertion subpattern is matched in the normal way, except that it does not cause the current matching position to be changed. Assertion subpatterns are not capturing subpatterns. If such an asser- tion contains capturing subpatterns within it, these are counted for the purposes of numbering the capturing subpatterns in the whole pat- tern. However, substring capturing is carried out only for positive assertions, because it does not make sense for negative assertions. For compatibility with Perl, assertion subpatterns may be repeated; though it makes no sense to assert the same thing several times, the side effect of capturing parentheses may occasionally be useful. In practice, there only three cases: (1) If the quantifier is {0}, the assertion is never obeyed during matching. However, it may contain internal capturing parenthesized groups that are called from elsewhere via the subroutine mechanism. (2) If quantifier is {0,n} where n is greater than zero, it is treated as if it were {0,1}. At run time, the rest of the pattern match is tried with and without the assertion, the order depending on the greed- iness of the quantifier. (3) If the minimum repetition is greater than zero, the quantifier is ignored. The assertion is obeyed just once when encountered during matching. Lookahead assertions Lookahead assertions start with (?= for positive assertions and (?! for negative assertions. For example, \w+(?=;) matches a word followed by a semicolon, but does not include the semi- colon in the match, and foo(?!bar) matches any occurrence of "foo" that is not followed by "bar". Note that the apparently similar pattern (?!foo)bar does not find an occurrence of "bar" that is preceded by something other than "foo"; it finds any occurrence of "bar" whatsoever, because the assertion (?!foo) is always true when the next three characters are "bar". A lookbehind assertion is needed to achieve the other effect. If you want to force a matching failure at some point in a pattern, the most convenient way to do it is with (?!) because an empty string always matches, so an assertion that requires there not to be an empty string must always fail. The backtracking control verb (*FAIL) or (*F) is a synonym for (?!). Lookbehind assertions Lookbehind assertions start with (?<= for positive assertions and (?)...) or (?('name')...) to test for a used subpattern by name. For compatibility with earlier versions of PCRE, which had this facility before Perl, the syntax (?(name)...) is also recognized. However, there is a possible ambiguity with this syn- tax, because subpattern names may consist entirely of digits. PCRE looks first for a named subpattern; if it cannot find one and the name consists entirely of digits, PCRE looks for a subpattern of that num- ber, which must be greater than zero. Using subpattern names that con- sist entirely of digits is not recommended. Rewriting the above example to use a named subpattern gives this: (? \( )? [^()]+ (?() \) ) If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them has matched. Checking for pattern recursion If the condition is the string (R), and there is no subpattern with the name R, the condition is true if a recursive call to the whole pattern or any subpattern has been made. If digits or a name preceded by amper- sand follow the letter R, for example: (?(R3)...) or (?(R&name)...) the condition is true if the most recent recursion is into a subpattern whose number or name is given. This condition does not check the entire recursion stack. If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them is the most recent recursion. At "top level", all these recursion test conditions are false. The syntax for recursive patterns is described below. Defining subpatterns for use by reference only If the condition is the string (DEFINE), and there is no subpattern with the name DEFINE, the condition is always false. In this case, there may be only one alternative in the subpattern. It is always skipped if control reaches this point in the pattern; the idea of DEFINE is that it can be used to define subroutines that can be refer- enced from elsewhere. (The use of subroutines is described below.) For example, a pattern to match an IPv4 address such as "192.168.23.245" could be written like this (ignore white space and line breaks): (?(DEFINE) (? 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) ) \b (?&byte) (\.(?&byte)){3} \b The first part of the pattern is a DEFINE group inside which a another group named "byte" is defined. This matches an individual component of an IPv4 address (a number less than 256). When matching takes place, this part of the pattern is skipped because DEFINE acts like a false condition. The rest of the pattern uses references to the named group to match the four dot-separated components of an IPv4 address, insist- ing on a word boundary at each end. Assertion conditions If the condition is not in any of the above formats, it must be an assertion. This may be a positive or negative lookahead or lookbehind assertion. Consider this pattern, again containing non-significant white space, and with the two alternatives on the second line: (?(?=[^a-z]*[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) The condition is a positive lookahead assertion that matches an optional sequence of non-letters followed by a letter. In other words, it tests for the presence of at least one letter in the subject. If a letter is found, the subject is matched against the first alternative; otherwise it is matched against the second. This pattern matches strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits. COMMENTS There are two ways of including comments in patterns that are processed by PCRE. In both cases, the start of the comment must not be in a char- acter class, nor in the middle of any other sequence of related charac- ters such as (?: or a subpattern name or number. The characters that make up a comment play no part in the pattern matching. The sequence (?# marks the start of a comment that continues up to the next closing parenthesis. Nested parentheses are not permitted. If the PCRE_EXTENDED option is set, an unescaped # character also introduces a comment, which in this case continues to immediately after the next newline character or character sequence in the pattern. Which charac- ters are interpreted as newlines is controlled by the options passed to a compiling function or by a special sequence at the start of the pat- tern, as described in the section entitled "Newline conventions" above. Note that the end of this type of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. For example, consider this pattern when PCRE_EXTENDED is set, and the default newline convention is in force: abc #comment \n still comment On encountering the # character, pcre_compile() skips along, looking for a newline in the pattern. The sequence \n is still literal at this stage, so it does not terminate the comment. Only an actual character with the code value 0x0a (the default newline) does so. RECURSIVE PATTERNS Consider the problem of matching a string in parentheses, allowing for unlimited nested parentheses. Without the use of recursion, the best that can be done is to use a pattern that matches up to some fixed depth of nesting. It is not possible to handle an arbitrary nesting depth. For some time, Perl has provided a facility that allows regular expres- sions to recurse (amongst other things). It does this by interpolating Perl code in the expression at run time, and the code can refer to the expression itself. A Perl pattern using code interpolation to solve the parentheses problem can be created like this: $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x; The (?p{...}) item interpolates Perl code at run time, and in this case refers recursively to the pattern in which it appears. Obviously, PCRE cannot support the interpolation of Perl code. Instead, it supports special syntax for recursion of the entire pattern, and also for individual subpattern recursion. After its introduction in PCRE and Python, this kind of recursion was subsequently introduced into Perl at release 5.10. A special item that consists of (? followed by a number greater than zero and a closing parenthesis is a recursive subroutine call of the subpattern of the given number, provided that it occurs inside that subpattern. (If not, it is a non-recursive subroutine call, which is described in the next section.) The special item (?R) or (?0) is a recursive call of the entire regular expression. This PCRE pattern solves the nested parentheses problem (assume the PCRE_EXTENDED option is set so that white space is ignored): \( ( [^()]++ | (?R) )* \) First it matches an opening parenthesis. Then it matches any number of substrings which can either be a sequence of non-parentheses, or a recursive match of the pattern itself (that is, a correctly parenthe- sized substring). Finally there is a closing parenthesis. Note the use of a possessive quantifier to avoid backtracking into sequences of non- parentheses. If this were part of a larger pattern, you would not want to recurse the entire pattern, so instead you could use this: ( \( ( [^()]++ | (?1) )* \) ) We have put the pattern into parentheses, and caused the recursion to refer to them instead of the whole pattern. In a larger pattern, keeping track of parenthesis numbers can be tricky. This is made easier by the use of relative references. Instead of (?1) in the pattern above you can write (?-2) to refer to the second most recently opened parentheses preceding the recursion. In other words, a negative number counts capturing parentheses leftwards from the point at which it is encountered. It is also possible to refer to subsequently opened parentheses, by writing references such as (?+2). However, these cannot be recursive because the reference is not inside the parentheses that are refer- enced. They are always non-recursive subroutine calls, as described in the next section. An alternative approach is to use named parentheses instead. The Perl syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also supported. We could rewrite the above example as follows: (? \( ( [^()]++ | (?&pn) )* \) ) If there is more than one subpattern with the same name, the earliest one is used. This particular example pattern that we have been looking at contains nested unlimited repeats, and so the use of a possessive quantifier for matching strings of non-parentheses is important when applying the pat- tern to strings that do not match. For example, when this pattern is applied to (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() it yields "no match" quickly. However, if a possessive quantifier is not used, the match runs for a very long time indeed because there are so many different ways the + and * repeats can carve up the subject, and all have to be tested before failure can be reported. At the end of a match, the values of capturing parentheses are those from the outermost level. If you want to obtain intermediate values, a callout function can be used (see below and the pcrecallout documenta- tion). If the pattern above is matched against (ab(cd)ef) the value for the inner capturing parentheses (numbered 2) is "ef", which is the last value taken on at the top level. If a capturing sub- pattern is not matched at the top level, its final captured value is unset, even if it was (temporarily) set at a deeper level during the matching process. 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 via pcre_free afterwards. If no memory can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error. Do not confuse the (?R) item with the condition (R), which tests for recursion. Consider this pattern, which matches text in angle brack- ets, allowing for arbitrary nesting. Only digits are allowed in nested brackets (that is, when recursing), whereas any characters are permit- ted at the outer level. < (?: (?(R) \d++ | [^<>]*+) | (?R)) * > In this pattern, (?(R) is the start of a conditional subpattern, with two different alternatives for the recursive and non-recursive cases. The (?R) item is the actual recursive call. Differences in recursion processing between PCRE and Perl Recursion processing in PCRE differs from Perl in two important ways. In PCRE (like Python, but unlike Perl), a recursive subpattern 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 there is a subsequent matching failure. This can be illustrated by the following pattern, which purports to match a palin- dromic string that contains an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"): ^(.|(.)(?1)\2)$ The idea is that it either matches a single character, or two identical characters surrounding a sub-palindrome. In Perl, this pattern works; in PCRE it does not if the pattern is longer than three characters. Consider the subject string "abcba": At the top level, the first character is matched, but as it is not at the end of the string, the first alternative fails; the second alterna- tive is taken and the recursion kicks in. The recursive call to subpat- tern 1 successfully matches the next character ("b"). (Note that the beginning and end of line tests are not part of the recursion). Back at the top level, the next character ("c") is compared with what subpattern 2 matched, which was "a". This fails. Because the recursion is treated as an atomic group, there are now no backtracking points, and so the entire match fails. (Perl is able, at this point, to re- enter the recursion and try the second alternative.) However, if the pattern is written with the alternatives in the other order, things are different: ^((.)(?1)\2|.)$ This time, the recursing alternative is tried first, and continues to recurse until it runs out of characters, at which point the recursion fails. But this time we do have another alternative to try at the higher level. That is the big difference: in the previous case the remaining alternative is at a deeper recursion level, which PCRE cannot use. To change the pattern so that it matches all palindromic strings, not just those with an odd number of characters, it is tempting to change the pattern to this: ^((.)(?1)\2|.?)$ Again, this works in Perl, but not in PCRE, and for the same reason. When a deeper recursion has matched a single character, it cannot be entered again in order to match an empty string. The solution is to separate the two cases, and write out the odd and even cases as alter- natives at the higher level: ^(?:((.)(?1)\2|)|((.)(?3)\4|.)) If you want to match typical palindromic phrases, the pattern has to ignore all non-word characters, which can be done like this: ^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$ If run with the PCRE_CASELESS option, this pattern matches phrases such as "A man, a plan, a canal: Panama!" and it works well in both PCRE and Perl. Note the use of the possessive quantifier *+ to avoid backtrack- ing into sequences of non-word characters. Without this, PCRE takes a great deal longer (ten times or more) to match typical phrases, and Perl takes so long that you think it has gone into a loop. WARNING: The palindrome-matching patterns above work only if the sub- ject string does not start with a palindrome that is shorter than the entire string. For example, although "abcba" is correctly matched, if the subject is "ababa", PCRE finds the palindrome "aba" at the start, then fails at top level because the end of the string does not follow. Once again, it cannot jump back into the recursion to try other alter- natives, so the entire match fails. The second way in which PCRE and Perl differ in their recursion pro- cessing is in the handling of captured values. In Perl, when a subpat- tern is called recursively or as a subpattern (see the next section), it has no access to any values that were captured outside the recur- sion, whereas in PCRE these values can be referenced. Consider this pattern: ^(.)(\1|a(?2)) In PCRE, this pattern matches "bab". The first capturing parentheses match "b", then in the second group, when the back reference \1 fails to match "b", the second alternative matches "a" and then recurses. In the recursion, \1 does now match "b" and so the whole match succeeds. In Perl, the pattern fails to match because inside the recursive call \1 cannot access the externally set value. SUBPATTERNS AS SUBROUTINES If the syntax for a recursive subpattern call (either by number or by name) is used outside the parentheses to which it refers, it operates like a subroutine in a programming language. The called subpattern may be defined before or after the reference. A numbered reference can be absolute or relative, as in these examples: (...(absolute)...)...(?2)... (...(relative)...)...(?-1)... (...(?+1)...(relative)... An earlier example pointed out that the pattern (sens|respons)e and \1ibility matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility". If instead the pattern (sens|respons)e and (?1)ibility is used, it does match "sense and responsibility" as well as the other two strings. Another example is given in the discussion of DEFINE above. All subroutine calls, whether recursive or not, are always treated as atomic groups. That is, once a subroutine has matched some of the sub- ject string, it is never re-entered, even if it contains untried alter- natives and there is a subsequent matching failure. Any capturing parentheses that are set during the subroutine call revert to their previous values afterwards. Processing options such as case-independence are fixed when a subpat- tern is defined, so if it is used as a subroutine, such options cannot be changed for different calls. For example, consider this pattern: (abc)(?i:(?-1)) It matches "abcabc". It does not match "abcABC" because the change of processing option does not affect the called subpattern. ONIGURUMA SUBROUTINE SYNTAX For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or a number enclosed either in angle brackets or single quotes, is an alternative syntax for referencing a subpattern as a subroutine, possibly recursively. Here are two of the examples used above, rewrit- ten using this syntax: (? \( ( (?>[^()]+) | \g )* \) ) (sens|respons)e and \g'1'ibility PCRE supports an extension to Oniguruma: if a number is preceded by a plus or a minus sign it is taken as a relative reference. For example: (abc)(?i:\g<-1>) Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not synonymous. The former is a back reference; the latter is a subroutine call. CALLOUTS Perl has a feature whereby using the sequence (?{...}) causes arbitrary 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 (8-bit library) or pcre16_callout (16-bit library). 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 points: (?C1)abc(?C2)def If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call- outs are automatically installed before each item in the pattern. They are all numbered 255. During matching, when PCRE reaches a callout point, the external func- tion 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 the matching function. The callout function may cause matching to proceed, to backtrack, or to fail altogether. A complete description of the interface to the callout function is given in the pcrecallout documentation. BACKTRACKING CONTROL Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which are described in the Perl documentation as "experimental and sub- ject to change or removal in a future version of Perl". It goes on to say: "Their usage in production code should be noted to avoid problems during upgrades." The same remarks apply to the PCRE features described in this section. Since these verbs are specifically related to backtracking, most of them can be used only when the pattern is to be matched using one of the traditional matching functions, which use a backtracking algorithm. With the exception of (*FAIL), which behaves like a failing negative assertion, they cause an error if encountered by a DFA matching func- tion. If any of these verbs are used in an assertion or in a subpattern that is called as a subroutine (whether or not recursively), their effect is confined to that subpattern; it does not extend to the surrounding pat- tern, with one exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a successful positive assertion is passed back when a match succeeds (compare capturing parentheses in assertions). Note that such subpatterns are processed as anchored at the point where they are tested. Note also that Perl's treatment of subroutines and assertions is different in some cases. The new verbs make use of what was previously invalid syntax: an open- ing parenthesis followed by an asterisk. They are generally of the form (*VERB) or (*VERB:NAME). Some may take either form, with differing be- haviour, depending on whether or not an argument is present. A name is any sequence of characters that does not include a closing parenthesis. The maximum length of name is 255 in the 8-bit library and 65535 in the 16-bit library. If the name is empty, that is, if the closing parenthe- sis immediately follows the colon, the effect is as if the colon were not there. Any number of these verbs may occur in a pattern. Optimizations that affect backtracking verbs PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it may know the minimum length of matching subject, or that a particular character must be present. When one of these optimizations suppresses the running of a match, any included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com- pile() or pcre_exec(), or by starting the pattern with (*NO_START_OPT). There is more discussion of this option in the section entitled "Option bits for pcre_exec()" in the pcreapi documentation. Experiments with Perl suggest that it too has similar optimizations, sometimes leading to anomalous results. Verbs that act immediately The following verbs act as soon as they are encountered. They may not be followed by a name. (*ACCEPT) This verb causes the match to end successfully, skipping the remainder of the pattern. However, when it is inside a subpattern that is called as a subroutine, only that subpattern is ended successfully. Matching then continues at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so far is captured. For example: A((?:A|B(*ACCEPT)|C)D) This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- tured by the outer parentheses. (*FAIL) or (*F) This verb causes a matching failure, forcing backtracking to occur. It is equivalent to (?!) but easier to read. The Perl documentation notes that it is probably useful only when combined with (?{}) or (??{}). Those are, of course, Perl features that are not present in PCRE. The nearest equivalent is the callout feature, as for example in this pat- tern: a+(?C)(*FAIL) A match with the string "aaaa" always fails, but the callout is taken before each backtrack happens (in this example, 10 times). Recording which path was taken There is one verb whose main purpose is to track how a match was arrived at, though it also has a secondary use in conjunction with advancing the match starting point (see (*SKIP) below). (*MARK:NAME) or (*:NAME) A name is always required with this verb. There may be as many instances of (*MARK) as you like in a pattern, and their names do not have to be unique. When a match succeeds, the name of the last-encountered (*MARK) on the matching path is passed back to the caller as described in the section entitled "Extra data for pcre_exec()" in the pcreapi documentation. Here is an example of pcretest output, where the /K modifier requests the retrieval and outputting of (*MARK) data: re> /X(*MARK:A)Y|X(*MARK:B)Z/K data> XY 0: XY MK: A XZ 0: XZ MK: B The (*MARK) name is tagged with "MK:" in this output, and in this exam- ple it indicates which of the two alternatives matched. This is a more efficient way of obtaining this information than putting each alterna- tive in its own capturing parentheses. If (*MARK) is encountered in a positive assertion, its name is recorded and passed back if it is the last-encountered. This does not happen for negative assertions. After a partial match or a failed match, the name of the last encoun- tered (*MARK) in the entire match process is returned. For example: re> /X(*MARK:A)Y|X(*MARK:B)Z/K data> XP No match, mark = B Note that in this unanchored example the mark is retained from the match attempt that started at the letter "X" in the subject. Subsequent match attempts starting at "P" and then with an empty string do not get as far as the (*MARK) item, but nevertheless do not reset it. If you are interested in (*MARK) values after failed matches, you should probably set the PCRE_NO_START_OPTIMIZE option (see above) to ensure that the match is always attempted. Verbs that act after backtracking The following verbs do nothing when they are encountered. Matching con- tinues with what follows, but if there is no subsequent match, causing a backtrack to the verb, a failure is forced. That is, backtracking cannot pass to the left of the verb. However, when one of these verbs appears inside an atomic group, its effect is confined to that group, because once the group has been matched, there is never any backtrack- ing into it. In this situation, backtracking can "jump back" to the left of the entire atomic group. (Remember also, as stated above, that this localization also applies in subroutine calls and assertions.) These verbs differ in exactly what kind of failure occurs when back- tracking reaches them. (*COMMIT) This verb, which may not be followed by a name, causes the whole match to fail outright if the rest of the pattern does not match. Even if the pattern is unanchored, no further attempts to find a match by advancing the starting point take place. Once (*COMMIT) has been passed, pcre_exec() is committed to finding a match at the current starting point, or not at all. For example: a+(*COMMIT)b This matches "xxaab" but not "aacaab". It can be thought of as a kind of dynamic anchor, or "I've started, so I must finish." The name of the most recently passed (*MARK) in the path is passed back when (*COMMIT) forces a match failure. Note that (*COMMIT) at the start of a pattern is not the same as an anchor, unless PCRE's start-of-match optimizations are turned off, as shown in this pcretest example: re> /(*COMMIT)abc/ data> xyzabc 0: abc xyzabc\Y No match PCRE knows that any match must start with "a", so the optimization skips along the subject to "a" before running the first match attempt, which succeeds. When the optimization is disabled by the \Y escape in the second subject, the match starts at "x" and so the (*COMMIT) causes it to fail without trying any other starting points. (*PRUNE) or (*PRUNE:NAME) This verb causes the match to fail at the current starting position in the subject if the rest of the pattern does not match. If the pattern is unanchored, the normal "bumpalong" advance to the next starting character then happens. Backtracking can occur as usual to the left of (*PRUNE), before it is reached, or when matching to the right of (*PRUNE), but if there is no match to the right, backtracking cannot cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alter- native to an atomic group or possessive quantifier, but there are some uses of (*PRUNE) that cannot be expressed in any other way. The behav- iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an anchored pattern (*PRUNE) has the same effect as (*COMMIT). (*SKIP) This verb, when given without a name, is like (*PRUNE), except that if the pattern is unanchored, the "bumpalong" advance is not to the next character, but to the position in the subject where (*SKIP) was encoun- tered. (*SKIP) signifies that whatever text was matched leading up to it cannot be part of a successful match. Consider: a+(*SKIP)b If the subject is "aaaac...", after the first match attempt fails (starting at the first character in the string), the starting point skips on to start the next attempt at "c". Note that a possessive quan- tifer does not have the same effect as this example; although it would suppress backtracking during the first match attempt, the second attempt would start at the second character instead of skipping on to "c". (*SKIP:NAME) When (*SKIP) has an associated name, its behaviour is modified. If the following pattern fails to match, the previous path through the pattern is searched for the most recent (*MARK) that has the same name. If one is found, the "bumpalong" advance is to the subject position that cor- responds to that (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a matching name is found, the (*SKIP) is ignored. (*THEN) or (*THEN:NAME) This verb causes a skip to the next innermost alternative if the rest of the pattern does not match. That is, it cancels pending backtrack- ing, but only within the current alternative. Its name comes from the observation that it can be used for a pattern-based if-then-else block: ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ... If the COND1 pattern matches, FOO is tried (and possibly further items after the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking into COND1. The behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts like (*PRUNE). Note that a subpattern that does not contain a | character is just a part of the enclosing alternative; it is not a nested alternation with only one alternative. The effect of (*THEN) extends beyond such a sub- pattern to the enclosing alternative. Consider this pattern, where A, B, etc. are complex pattern fragments that do not contain any | charac- ters at this level: A (B(*THEN)C) | D If A and B are matched, but there is a failure in C, matching does not backtrack into A; instead it moves to the next alternative, that is, D. However, if the subpattern containing (*THEN) is given an alternative, it behaves differently: A (B(*THEN)C | (*FAIL)) | D The effect of (*THEN) is now confined to the inner subpattern. After a failure in C, matching moves to (*FAIL), which causes the whole subpat- tern to fail because there are no more alternatives to try. In this case, matching does now backtrack into A. Note also that a conditional subpattern is not considered as having two alternatives, because only one is ever used. In other words, the | character in a conditional subpattern has a different meaning. Ignoring white space, consider: ^.*? (?(?=a) a | b(*THEN)c ) If the subject is "ba", this pattern does not match. Because .*? is ungreedy, it initially matches zero characters. The condition (?=a) then fails, the character "b" is matched, but "c" is not. At this point, matching does not backtrack to .*? as might perhaps be expected from the presence of the | character. The conditional subpattern is part of the single alternative that comprises the whole pattern, and so the match fails. (If there was a backtrack into .*?, allowing it to match "b", the match would succeed.) The verbs just described provide four different "strengths" of control when subsequent matching fails. (*THEN) is the weakest, carrying on the match at the next alternative. (*PRUNE) comes next, failing the match at the current starting position, but allowing an advance to the next character (for an unanchored pattern). (*SKIP) is similar, except that the advance may be more than one character. (*COMMIT) is the strongest, causing the entire match to fail. If more than one such verb is present in a pattern, the "strongest" one wins. For example, consider this pattern, where A, B, etc. are complex pattern fragments: (A(*COMMIT)B(*THEN)C|D) Once A has matched, PCRE is committed to this match, at the current starting position. If subsequently B matches, but C does not, the nor- mal (*THEN) action of trying the next alternative (that is, D) does not happen because (*COMMIT) overrides. SEE ALSO pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3), pcre16(3). AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 17 June 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCRESYNTAX(3) PCRESYNTAX(3) NAME PCRE - Perl-compatible regular expressions PCRE REGULAR EXPRESSION SYNTAX SUMMARY The full syntax and semantics of the regular expressions that are sup- ported by PCRE are described in the pcrepattern documentation. This document contains a quick-reference summary of the syntax. QUOTING \x where x is non-alphanumeric is a literal x \Q...\E treat enclosed characters as literal CHARACTERS \a alarm, that is, the BEL character (hex 07) \cx "control-x", where x is any ASCII character \e escape (hex 1B) \f form feed (hex 0C) \n newline (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) \ddd character with octal code ddd, or backreference \xhh character with hex code hh \x{hhh..} character with hex code hhh.. CHARACTER TYPES . any character except newline; in dotall mode, any character whatsoever \C one data unit, even in UTF mode (best avoided) \d a decimal digit \D a character that is not a decimal digit \h a horizontal white space character \H a character that is not a horizontal white space character \N a character that is not a newline \p{xx} a character with the xx property \P{xx} a character without the xx property \R a newline sequence \s a white space character \S a character that is not a white space character \v a vertical white space character \V a character that is not a vertical white space character \w a "word" character \W a "non-word" character \X an extended Unicode sequence In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII characters, even in a UTF mode. However, this can be changed by setting the PCRE_UCP option. GENERAL CATEGORY PROPERTIES FOR \p and \P C Other Cc Control Cf Format Cn Unassigned Co Private use Cs Surrogate L Letter Ll Lower case letter Lm Modifier letter Lo Other letter Lt Title case letter Lu Upper case letter L& Ll, Lu, or Lt M Mark Mc Spacing mark Me Enclosing mark Mn Non-spacing mark N Number Nd Decimal number Nl Letter number No Other number P Punctuation Pc Connector punctuation Pd Dash punctuation Pe Close punctuation Pf Final punctuation Pi Initial punctuation Po Other punctuation Ps Open punctuation S Symbol Sc Currency symbol Sk Modifier symbol Sm Mathematical symbol So Other symbol Z Separator Zl Line separator Zp Paragraph separator Zs Space separator PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P Xan Alphanumeric: union of properties L and N Xps POSIX space: property Z or tab, NL, VT, FF, CR Xsp Perl space: property Z or tab, NL, FF, CR Xwd Perl word: property Xan or underscore SCRIPT NAMES FOR \p AND \P Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi. CHARACTER CLASSES [...] positive character class [^...] negative character class [x-y] range (can be used for hex characters) [[:xxx:]] positive POSIX named set [[:^xxx:]] negative POSIX named set alnum alphanumeric alpha alphabetic ascii 0-127 blank space or tab cntrl control character digit decimal digit graph printing, excluding space lower lower case letter print printing, including space punct printing, excluding alphanumeric space white space upper upper case letter word same as \w xdigit hexadecimal digit In PCRE, POSIX character set names recognize only ASCII characters by default, but some of them use Unicode properties if PCRE_UCP is set. You can use \Q...\E inside a character class. QUANTIFIERS ? 0 or 1, greedy ?+ 0 or 1, possessive ?? 0 or 1, lazy * 0 or more, greedy *+ 0 or more, possessive *? 0 or more, lazy + 1 or more, greedy ++ 1 or more, possessive +? 1 or more, lazy {n} exactly n {n,m} at least n, no more than m, greedy {n,m}+ at least n, no more than m, possessive {n,m}? at least n, no more than m, lazy {n,} n or more, greedy {n,}+ n or more, possessive {n,}? n or more, lazy ANCHORS AND SIMPLE ASSERTIONS \b word boundary \B not a word boundary ^ start of subject also after internal newline in multiline mode \A start of subject $ end of subject also before newline at end of subject also before internal newline in multiline mode \Z end of subject also before newline at end of subject \z end of subject \G first matching position in subject MATCH POINT RESET \K reset start of match ALTERNATION expr|expr|expr... CAPTURING (...) capturing group (?...) named capturing group (Perl) (?'name'...) named capturing group (Perl) (?P...) named capturing group (Python) (?:...) non-capturing group (?|...) non-capturing group; reset group numbers for capturing groups in each alternative ATOMIC GROUPS (?>...) atomic, non-capturing group COMMENT (?#....) comment (not nestable) OPTION SETTING (?i) caseless (?J) allow duplicate names (?m) multiline (?s) single line (dotall) (?U) default ungreedy (lazy) (?x) extended (ignore white space) (?-...) unset option(s) The following are recognized only at the start of a pattern or after one of the newline-setting options with similar syntax: (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) (*UCP) set PCRE_UCP (use Unicode properties for \d etc) LOOKAHEAD AND LOOKBEHIND ASSERTIONS (?=...) positive look ahead (?!...) negative look ahead (?<=...) positive look behind (? reference by name (Perl) \k'name' reference by name (Perl) \g{name} reference by name (Perl) \k{name} reference by name (.NET) (?P=name) reference by name (Python) SUBROUTINE REFERENCES (POSSIBLY RECURSIVE) (?R) recurse whole pattern (?n) call subpattern by absolute number (?+n) call subpattern by relative number (?-n) call subpattern by relative number (?&name) call subpattern by name (Perl) (?P>name) call subpattern by name (Python) \g call subpattern by name (Oniguruma) \g'name' call subpattern by name (Oniguruma) \g call subpattern by absolute number (Oniguruma) \g'n' call subpattern by absolute number (Oniguruma) \g<+n> call subpattern by relative number (PCRE extension) \g'+n' call subpattern by relative number (PCRE extension) \g<-n> call subpattern by relative number (PCRE extension) \g'-n' call subpattern by relative number (PCRE extension) CONDITIONAL PATTERNS (?(condition)yes-pattern) (?(condition)yes-pattern|no-pattern) (?(n)... absolute reference condition (?(+n)... relative reference condition (?(-n)... relative reference condition (?()... named reference condition (Perl) (?('name')... named reference condition (Perl) (?(name)... named reference condition (PCRE) (?(R)... overall recursion condition (?(Rn)... specific group recursion condition (?(R&name)... specific recursion condition (?(DEFINE)... define subpattern for reference (?(assert)... assertion condition BACKTRACKING CONTROL The following act immediately they are reached: (*ACCEPT) force successful match (*FAIL) force backtrack; synonym (*F) (*MARK:NAME) set name to be passed back; synonym (*:NAME) The following act only when a subsequent match failure causes a back- track to reach them. They all force a match failure, but they differ in what happens afterwards. Those that advance the start-of-match point do so only if the pattern is not anchored. (*COMMIT) overall failure, no advance of starting point (*PRUNE) advance to next starting character (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE) (*SKIP) advance to current matching position (*SKIP:NAME) advance to position corresponding to an earlier (*MARK:NAME); if not found, the (*SKIP) is ignored (*THEN) local failure, backtrack to next alternation (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN) NEWLINE CONVENTIONS These are recognized only at the very start of the pattern or after a (*BSR_...), (*UTF8), (*UTF16) or (*UCP) option. (*CR) carriage return only (*LF) linefeed only (*CRLF) carriage return followed by linefeed (*ANYCRLF) all three of the above (*ANY) any Unicode newline sequence WHAT \R MATCHES These are recognized only at the very start of the pattern or after a (*...) option that sets the newline convention or a UTF or UCP mode. (*BSR_ANYCRLF) CR, LF, or CRLF (*BSR_UNICODE) any Unicode newline sequence CALLOUTS (?C) callout (?Cn) callout with data n SEE ALSO pcrepattern(3), pcreapi(3), pcrecallout(3), pcrematching(3), pcre(3). AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREUNICODE(3) PCREUNICODE(3) NAME PCRE - Perl-compatible regular expressions UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT From Release 8.30, in addition to its previous UTF-8 support, PCRE also supports UTF-16 by means of a separate 16-bit library. This can be built as well as, or instead of, the 8-bit library. UTF-8 SUPPORT In order process UTF-8 strings, you must build PCRE's 8-bit library with UTF support, and, in addition, you must call pcre_compile() with the PCRE_UTF8 option flag, or the pattern must start with the sequence (*UTF8). When either of these is the case, both the pattern and any subject strings that are matched against it are treated as UTF-8 strings instead of strings of 1-byte characters. UTF-16 SUPPORT In order process UTF-16 strings, you must build PCRE's 16-bit library with UTF support, and, in addition, you must call pcre16_compile() with the PCRE_UTF16 option flag, or the pattern must start with the sequence (*UTF16). When either of these is the case, both the pattern and any subject strings that are matched against it are treated as UTF-16 strings instead of strings of 16-bit characters. UTF SUPPORT OVERHEAD If you compile PCRE with UTF support, but do not use it at run time, the library will be a bit bigger, but the additional run time overhead is limited to testing the PCRE_UTF8/16 flag occasionally, so should not be very big. UNICODE PROPERTY SUPPORT If PCRE is built with Unicode character property support (which implies UTF support), the escape sequences \p{..}, \P{..}, and \X can be used. The available properties that can be tested are limited to the general category properties such as Lu for an upper case letter or Nd for a decimal number, the Unicode script names such as Arabic or Han, and the derived properties Any and L&. A full list is given in the pcrepattern documentation. Only the short names for properties are supported. For example, \p{L} matches a letter. Its Perl synonym, \p{Letter}, is not supported. Furthermore, in Perl, many properties may optionally be prefixed by "Is", for compatibility with Perl 5.6. PCRE does not sup- port this. Validity of UTF-8 strings When you set the PCRE_UTF8 flag, the byte strings passed as patterns and subjects are (by default) checked for validity on entry to the rel- evant functions. The entire string is checked before any other process- ing takes place. From release 7.3 of PCRE, the check is according the rules of RFC 3629, which are themselves derived from the Unicode speci- fication. Earlier releases of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0 to U+10FFFF, exclud- ing U+D800 to U+DFFF. The excluded code points are the "Surrogate Area" of Unicode. They are reserved for use by UTF-16, where they are used in pairs to encode codepoints with values greater than 0xFFFF. The code points that are encoded by UTF-16 pairs are available independently in the UTF-8 encod- ing. (In other words, the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8.) If an invalid UTF-8 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first byte of the failing character. The run-time functions pcre_exec() and pcre_dfa_exec() also pass back this information, as well as a more detailed reason code if the caller has provided memory in which to do this. In some situations, you may already know that your strings are valid, and therefore want to skip these checks in order to improve perfor- mance, for example in the case of a long subject string that is being scanned repeatedly with different patterns. If you set the PCRE_NO_UTF8_CHECK flag at compile time or at run time, PCRE assumes that the pattern or subject it is given (respectively) contains only valid UTF-8 codes. In this case, it does not diagnose an invalid UTF-8 string. If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what happens depends on why the string is invalid. If the string con- forms to the "old" definition of UTF-8 (RFC 2279), it is processed as a string of characters in the range 0 to 0x7FFFFFFF by pcre_dfa_exec() and the interpreted version of pcre_exec(). In other words, apart from the initial validity test, these functions (when in UTF-8 mode) handle strings according to the more liberal rules of RFC 2279. However, the just-in-time (JIT) optimization for pcre_exec() supports only RFC 3629. If you are using JIT optimization, or if the string does not even con- form to RFC 2279, the result is undefined. Your program may crash. If you want to process strings of values in the full range 0 to 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this situation, you will have to apply your own validity check, and avoid the use of JIT optimization. Validity of UTF-16 strings When you set the PCRE_UTF16 flag, the strings of 16-bit data units that are passed as patterns and subjects are (by default) checked for valid- ity on entry to the relevant functions. Values other than those in the surrogate range U+D800 to U+DFFF are independent code points. Values in the surrogate range must be used in pairs in the correct manner. If an invalid UTF-16 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first data unit of the failing character. The run-time functions pcre16_exec() and pcre16_dfa_exec() also pass back this information, as well as a more detailed reason code if the caller has provided memory in which to do this. In some situations, you may already know that your strings are valid, and therefore want to skip these checks in order to improve perfor- mance. If you set the PCRE_NO_UTF16_CHECK flag at compile time or at run time, PCRE assumes that the pattern or subject it is given (respec- tively) contains only valid UTF-16 sequences. In this case, it does not diagnose an invalid UTF-16 string. General comments about UTF modes 1. Codepoints less than 256 can be specified by either braced or unbraced hexadecimal escape sequences (for example, \x{b3} or \xb3). Larger values have to use braced sequences. 2. Octal numbers up to \777 are recognized, and in UTF-8 mode, they match two-byte characters for values greater than \177. 3. Repeat quantifiers apply to complete UTF characters, not to individ- ual data units, for example: \x{100}{3}. 4. The dot metacharacter matches one UTF character instead of a single data unit. 5. The escape sequence \C can be used to match a single byte in UTF-8 mode, or a single 16-bit data unit in UTF-16 mode, but its use can lead to some strange effects because it breaks up multi-unit characters (see the description of \C in the pcrepattern documentation). The use of \C is not supported in the alternative matching function pcre[16]_dfa_exec(), nor is it supported in UTF mode by the JIT opti- mization of pcre[16]_exec(). If JIT optimization is requested for a UTF pattern that contains \C, it will not succeed, and so the matching will be carried out by the normal interpretive function. 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly test characters of any code value, but, by default, the characters that PCRE recognizes as digits, spaces, or word characters remain the same set as in non-UTF mode, all with values less than 256. This remains true even when PCRE is built to include Unicode property support, because to do otherwise would slow down PCRE in many common cases. Note in particular that this applies to \b and \B, because they are defined in terms of \w and \W. If you really want to test for a wider sense of, say, "digit", you can use explicit Unicode property tests such as \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that the character escapes work is changed so that Unicode properties are used to determine which characters match. There are more details in the sec- tion on generic character types in the pcrepattern documentation. 7. Similarly, characters that match the POSIX named character classes are all low-valued characters, unless the PCRE_UCP option is set. 8. However, the horizontal and vertical white space matching escapes (\h, \H, \v, and \V) do match all the appropriate Unicode characters, whether or not PCRE_UCP is set. 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. Furthermore, 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 map- pings in Unicode; these are not supported by PCRE. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 14 April 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREJIT(3) PCREJIT(3) NAME PCRE - Perl-compatible regular expressions PCRE JUST-IN-TIME COMPILER SUPPORT Just-in-time compiling is a heavyweight optimization that can greatly speed up pattern matching. However, it comes at the cost of extra pro- cessing before the match is performed. Therefore, it is of most benefit when the same pattern is going to be matched many times. This does not necessarily mean many calls of a matching function; if the pattern is not anchored, matching attempts may take place many times at various positions in the subject, even for a single call. Therefore, if the subject string is very long, it may still pay to use JIT for one-off matches. JIT support applies only to the traditional Perl-compatible matching function. It does not apply when the DFA matching function is being used. The code for this support was written by Zoltan Herczeg. 8-BIT and 16-BIT SUPPORT JIT support is available for both the 8-bit and 16-bit PCRE libraries. To keep this documentation simple, only the 8-bit interface is described in what follows. If you are using the 16-bit library, substi- tute the 16-bit functions and 16-bit structures (for example, pcre16_jit_stack instead of pcre_jit_stack). AVAILABILITY OF JIT SUPPORT JIT support is an optional feature of PCRE. The "configure" option --enable-jit (or equivalent CMake option) must be set when PCRE is built if you want to use JIT. The support is limited to the following hardware platforms: ARM v5, v7, and Thumb2 Intel x86 32-bit and 64-bit MIPS 32-bit Power PC 32-bit and 64-bit If --enable-jit is set on an unsupported platform, compilation fails. A program that is linked with PCRE 8.20 or later can tell if JIT sup- port is available by calling pcre_config() with the PCRE_CONFIG_JIT option. The result is 1 when JIT is available, and 0 otherwise. How- ever, a simple program does not need to check this in order to use JIT. The API is implemented in a way that falls back to the interpretive code if JIT is not available. If your program may sometimes be linked with versions of PCRE that are older than 8.20, but you want to use JIT when it is available, you can test the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT macro such as PCRE_CONFIG_JIT, for compile-time control of your code. SIMPLE USE OF JIT You have to do two things to make use of the JIT support in the sim- plest way: (1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for each compiled pattern, and pass the resulting pcre_extra block to pcre_exec(). (2) Use pcre_free_study() to free the pcre_extra block when it is no longer needed, instead of just freeing it yourself. This ensures that any JIT data is also freed. For a program that may be linked with pre-8.20 versions of PCRE, you can insert #ifndef PCRE_STUDY_JIT_COMPILE #define PCRE_STUDY_JIT_COMPILE 0 #endif so that no option is passed to pcre_study(), and then use something like this to free the study data: #ifdef PCRE_CONFIG_JIT pcre_free_study(study_ptr); #else pcre_free(study_ptr); #endif PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for complete matches. If you want to run partial matches using the PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of pcre_exec(), you should set one or both of the following options in addition to, or instead of, PCRE_STUDY_JIT_COMPILE when you call pcre_study(): PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE The JIT compiler generates different optimized code for each of the three modes (normal, soft partial, hard partial). When pcre_exec() is called, the appropriate code is run if it is available. Otherwise, the pattern is matched using interpretive code. In some circumstances you may need to call additional functions. These are described in the section entitled "Controlling the JIT stack" below. If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ignored, and no JIT data is created. Otherwise, the compiled pattern is passed to the JIT compiler, which turns it into machine code that exe- cutes much faster than the normal interpretive code. When pcre_exec() is passed a pcre_extra block containing a pointer to JIT code of the appropriate mode (normal or hard/soft partial), it obeys that code instead of running the interpreter. The result is identical, but the compiled JIT code runs much faster. There are some pcre_exec() options that are not supported for JIT exe- cution. There are also some pattern items that JIT cannot handle. Details are given below. In both cases, execution automatically falls back to the interpretive code. If you want to know whether JIT was actually used for a particular match, you should arrange for a JIT callback function to be set up as described in the section entitled "Controlling the JIT stack" below, even if you do not need to supply a non-default JIT stack. Such a callback function is called whenever JIT code is about to be obeyed. If the execution options are not right for JIT execution, the callback function is not obeyed. If the JIT compiler finds an unsupported item, no JIT data is gener- ated. You can find out if JIT execution is available after studying a pattern by calling pcre_fullinfo() with the PCRE_INFO_JIT option. A result of 1 means that JIT compilation was successful. A result of 0 means that JIT support is not available, or the pattern was not studied with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to handle the pattern. Once a pattern has been studied, with or without JIT, it can be used as many times as you like for matching different subject strings. UNSUPPORTED OPTIONS AND PATTERN ITEMS The only pcre_exec() options that are supported for JIT execution are PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PAR- TIAL_SOFT. The unsupported pattern items are: \C match a single byte; not supported in UTF-8 mode (?Cn) callouts (*PRUNE) ) (*SKIP) ) backtracking control verbs (*THEN) ) Support for some of these may be added in future. RETURN VALUES FROM JIT EXECUTION When a pattern is matched using JIT execution, the return values are the same as those given by the interpretive pcre_exec() code, with the addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means that the memory used for the JIT stack was insufficient. See "Control- ling the JIT stack" below for a discussion of JIT stack usage. For com- patibility with the interpretive pcre_exec() code, no more than two- thirds of the ovector argument is used for passing back captured sub- strings. The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if searching a very large pattern tree goes on for too long, as it is in the same circumstance when JIT is not used, but the details of exactly what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error code is never returned by JIT execution. SAVING AND RESTORING COMPILED PATTERNS The code that is generated by the JIT compiler is architecture-spe- cific, and is also position dependent. For those reasons it cannot be saved (in a file or database) and restored later like the bytecode and other data of a compiled pattern. Saving and restoring compiled pat- terns is not something many people do. More detail about this facility is given in the pcreprecompile documentation. It should be possible to run pcre_study() on a saved and restored pattern, and thereby recreate the JIT data, but because JIT compilation uses significant resources, it is probably not worth doing this; you might as well recompile the original pattern. CONTROLLING THE JIT STACK When the compiled JIT code runs, it needs a block of memory to use as a stack. By default, it uses 32K on the machine stack. However, some large or complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack. Three functions are provided for managing blocks of memory for use as JIT stacks. There is further discussion about the use of JIT stacks in the section entitled "JIT stack FAQ" below. The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments are a starting size and a maximum size, and it returns a pointer to an opaque structure of type pcre_jit_stack, or NULL if there is an error. The pcre_jit_stack_free() function can be used to free a stack that is no longer needed. (For the technically minded: the address space is allocated by mmap or VirtualAlloc.) JIT uses far less memory for recursion than the interpretive code, and a maximum stack size of 512K to 1M should be more than enough for any pattern. The pcre_assign_jit_stack() function specifies which stack JIT code should use. Its arguments are as follows: pcre_extra *extra pcre_jit_callback callback void *data The extra argument must be the result of studying a pattern with PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other two options: (1) If callback is NULL and data is NULL, an internal 32K block on the machine stack is used. (2) If callback is NULL and data is not NULL, data must be a valid JIT stack, the result of calling pcre_jit_stack_alloc(). (3) If callback is not NULL, it must point to a function that is called with data as an argument at the start of matching, in order to set up a JIT stack. If the return from the callback function is NULL, the internal 32K stack is used; otherwise the return value must be a valid JIT stack, the result of calling pcre_jit_stack_alloc(). A callback function is obeyed whenever JIT code is about to be run; it is not obeyed when pcre_exec() is called with options that are incom- patible for JIT execution. A callback function can therefore be used to determine whether a match operation was executed by JIT or by the interpreter. You may safely use the same JIT stack for more than one pattern (either by assigning directly or by callback), as long as the patterns are all matched sequentially in the same thread. In a multithread application, if you do not specify a JIT stack, or if you assign or pass back NULL from a callback, that is thread-safe, because each thread has its own machine stack. However, if you assign or pass back a non-NULL JIT stack, this must be a different stack for each thread so that the application is thread-safe. Strictly speaking, even more is allowed. You can assign the same non- NULL stack to any number of patterns as long as they are not used for matching by multiple threads at the same time. For example, you can assign the same stack to all compiled patterns, and use a global mutex in the callback to wait until the stack is available for use. However, this is an inefficient solution, and not recommended. This is a suggestion for how a multithreaded program that needs to set up non-default JIT stacks might operate: During thread initalization thread_local_var = pcre_jit_stack_alloc(...) During thread exit pcre_jit_stack_free(thread_local_var) Use a one-line callback function return thread_local_var All the functions described in this section do nothing if JIT is not available, and pcre_assign_jit_stack() does nothing unless the extra argument is non-NULL and points to a pcre_extra block that is the result of a successful study with PCRE_STUDY_JIT_COMPILE etc. JIT STACK FAQ (1) Why do we need JIT stacks? PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack where the local data of the current node is pushed before checking its child nodes. Allocating real machine stack on some platforms is diffi- cult. For example, the stack chain needs to be updated every time if we extend the stack on PowerPC. Although it is possible, its updating time overhead decreases performance. So we do the recursion in memory. (2) Why don't we simply allocate blocks of memory with malloc()? Modern operating systems have a nice feature: they can reserve an address space instead of allocating memory. We can safely allocate mem- ory pages inside this address space, so the stack could grow without moving memory data (this is important because of pointers). Thus we can allocate 1M address space, and use only a single memory page (usually 4K) if that is enough. However, we can still grow up to 1M anytime if needed. (3) Who "owns" a JIT stack? The owner of the stack is the user program, not the JIT studied pattern or anything else. The user program must ensure that if a stack is used by pcre_exec(), (that is, it is assigned to the pattern currently run- ning), that stack must not be used by any other threads (to avoid over- writing the same memory area). The best practice for multithreaded pro- grams is to allocate a stack for each thread, and return this stack through the JIT callback function. (4) When should a JIT stack be freed? You can free a JIT stack at any time, as long as it will not be used by pcre_exec() again. When you assign the stack to a pattern, only a pointer is set. There is no reference counting or any other magic. You can free the patterns and stacks in any order, anytime. Just do not call pcre_exec() with a pattern pointing to an already freed stack, as that will cause SEGFAULT. (Also, do not free a stack currently used by pcre_exec() in another thread). You can also replace the stack for a pattern at any time. You can even free the previous stack before assigning a replacement. (5) Should I allocate/free a stack every time before/after calling pcre_exec()? No, because this is too costly in terms of resources. However, you could implement some clever idea which release the stack if it is not used in let's say two minutes. The JIT callback can help to achive this without keeping a list of the currently JIT studied patterns. (6) OK, the stack is for long term memory allocation. But what happens if a pattern causes stack overflow with a stack of 1M? Is that 1M kept until the stack is freed? Especially on embedded sytems, it might be a good idea to release mem- ory sometimes without freeing the stack. There is no API for this at the moment. Probably a function call which returns with the currently allocated memory for any stack and another which allows releasing mem- ory (shrinking the stack) would be a good idea if someone needs this. (7) This is too much of a headache. Isn't there any better solution for JIT stack handling? No, thanks to Windows. If POSIX threads were used everywhere, we could throw out this complicated API. EXAMPLE CODE This is a single-threaded example that specifies a JIT stack without using a callback. int rc; int ovector[30]; pcre *re; pcre_extra *extra; pcre_jit_stack *jit_stack; re = pcre_compile(pattern, 0, &error, &erroffset, NULL); /* Check for errors */ extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error); jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); /* Check for error (NULL) */ pcre_assign_jit_stack(extra, NULL, jit_stack); rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30); /* Check results */ pcre_free(re); pcre_free_study(extra); pcre_jit_stack_free(jit_stack); SEE ALSO pcreapi(3) AUTHOR Philip Hazel (FAQ by Zoltan Herczeg) University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 04 May 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREPARTIAL(3) PCREPARTIAL(3) NAME PCRE - Perl-compatible regular expressions PARTIAL MATCHING IN PCRE In normal use of PCRE, if the subject string that is passed to a match- ing function matches as far as it goes, but is too short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances where it might be helpful to distinguish this case from other cases in which there is no match. Consider, for example, an application where a human is required to type in data for a field with specific formatting requirements. An example might be a date in the form ddmmmyy, defined by this pattern: ^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$ If the application sees the user's keystrokes one by one, and can check that what has been typed so far is potentially valid, it is able to raise an error as soon as a mistake is made, by beeping and not reflecting the character that has been typed, for example. This immedi- ate feedback is likely to be a better user interface than a check that is delayed until the entire string has been entered. Partial matching can also be useful when the subject string is very long and is not all available at once. PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and PCRE_PARTIAL_HARD options, which can be set when calling any of the matching functions. For backwards compatibility, PCRE_PARTIAL is a syn- onym for PCRE_PARTIAL_SOFT. The essential difference between the two options is whether or not a partial match is preferred to an alterna- tive complete match, though the details differ between the two types of matching function. If both options are set, PCRE_PARTIAL_HARD takes precedence. If you want to use partial matching with just-in-time optimized code, you must call pcre_study() or pcre16_study() with one or both of these options: PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non- partial matches on the same pattern. If the appropriate JIT study mode has not been set for a match, the interpretive matching code is used. Setting a partial matching option disables two of PCRE's standard opti- mizations. PCRE remembers the last literal data unit in a pattern, and abandons matching immediately if it is not present in the subject string. This optimization cannot be used for a subject string that might match only partially. If the pattern was studied, PCRE knows the minimum length of a matching string, and does not bother to run the matching function on shorter strings. This optimization is also dis- abled for partial matching. PARTIAL MATCHING USING pcre_exec() OR pcre16_exec() A partial match occurs during a call to pcre_exec() or pcre16_exec() when the end of the subject string is reached successfully, but match- ing cannot continue because more characters are needed. However, at least one character in the subject must have been inspected. This char- acter need not form part of the final matched string; lookbehind asser- tions and the \K escape sequence provide ways of inspecting characters before the start of a matched substring. The requirement for inspecting at least one character exists because an empty string can always be matched; without such a restriction there would always be a partial match of an empty string at the end of the subject. If there are at least two slots in the offsets vector when a partial match is returned, the first slot is set to the offset of the earliest character that was inspected. For convenience, the second offset points to the end of the subject so that a substring can easily be identified. For the majority of patterns, the first offset identifies the start of the partially matched string. However, for patterns that contain look- behind assertions, or \K, or begin with \b or \B, earlier characters have been inspected while carrying out the match. For example: /(?<=abc)123/ This pattern matches "123", but only if it is preceded by "abc". If the subject string is "xyzabc12", the offsets after a partial match are for the substring "abc12", because all these characters are needed if another match is tried with extra characters added to the subject. What happens when a partial match is identified depends on which of the two partial matching options are set. PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec() If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre16_exec() identi- fies a partial match, the partial match is remembered, but matching continues as normal, and other alternatives in the pattern are tried. If no complete match can be found, PCRE_ERROR_PARTIAL is returned instead of PCRE_ERROR_NOMATCH. This option is "soft" because it prefers a complete match over a par- tial match. All the various matching items in a pattern behave as if the subject string is potentially complete. For example, \z, \Z, and $ match at the end of the subject, as normal, and for \b and \B the end of the subject is treated as a non-alphanumeric. If there is more than one partial match, the first one that was found provides the data that is returned. Consider this pattern: /123\w+X|dogY/ If this is matched against the subject string "abc123dog", both alter- natives fail to match, but the end of the subject is reached during matching, so PCRE_ERROR_PARTIAL is returned. The offsets are set to 3 and 9, identifying "123dog" as the first partial match that was found. (In this example, there are two partial matches, because "dog" on its own partially matches the second alternative.) PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec() If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre16_exec(), PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, without continuing to search for possible complete matches. This option is "hard" because it prefers an earlier partial match over a later com- plete match. For this reason, the assumption is made that the end of the supplied subject string may not be the true end of the available data, and so, if \z, \Z, \b, \B, or $ are encountered at the end of the subject, the result is PCRE_ERROR_PARTIAL, provided that at least one character in the subject has been inspected. Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 subject strings are checked for validity. Normally, an invalid sequence causes the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the special case of a truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when PCRE_PARTIAL_HARD is set. Comparing hard and soft partial matching The difference between the two partial matching options can be illus- trated by a pattern such as: /dog(sbody)?/ This matches either "dog" or "dogsbody", greedily (that is, it prefers the longer string if possible). If it is matched against the string "dog" with PCRE_PARTIAL_SOFT, it yields a complete match for "dog". However, if PCRE_PARTIAL_HARD is set, the result is PCRE_ERROR_PARTIAL. On the other hand, if the pattern is made ungreedy the result is dif- ferent: /dog(sbody)??/ In this case the result is always a complete match because that is found first, and matching never continues after finding a complete match. It might be easier to follow this explanation by thinking of the two patterns like this: /dog(sbody)?/ is the same as /dogsbody|dog/ /dog(sbody)??/ is the same as /dog|dogsbody/ The second pattern will never match "dogsbody", because it will always find the shorter match first. PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec() The DFA functions move along the subject string character by character, without backtracking, searching for all possible matches simultane- ously. If the end of the subject is reached before the end of the pat- tern, there is the possibility of a partial match, again provided that at least one character has been inspected. When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there have been no complete matches. Otherwise, the complete matches are returned. However, if PCRE_PARTIAL_HARD is set, a partial match takes precedence over any complete matches. The portion of the string that was inspected when the longest partial match was found is set as the first matching string, provided there are at least two slots in the offsets vector. Because the DFA functions always search for all possible matches, and there is no difference between greedy and ungreedy repetition, their behaviour is different from the standard functions when PCRE_PAR- TIAL_HARD is set. Consider the string "dog" matched against the ungreedy pattern shown above: /dog(sbody)??/ Whereas the standard functions stop as soon as they find the complete match for "dog", the DFA functions also find the partial match for "dogsbody", and so return that when PCRE_PARTIAL_HARD is set. PARTIAL MATCHING AND WORD BOUNDARIES If a pattern ends with one of sequences \b or \B, which test for word boundaries, partial matching with PCRE_PARTIAL_SOFT can give counter- intuitive results. Consider this pattern: /\bcat\b/ This matches "cat", provided there is a word boundary at either end. If the subject string is "the cat", the comparison of the final "t" with a following character cannot take place, so a partial match is found. However, normal matching carries on, and \b matches at the end of the subject when the last character is a letter, so a complete match is found. The result, therefore, is not PCRE_ERROR_PARTIAL. Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because then the partial match takes precedence. FORMERLY RESTRICTED PATTERNS For releases of PCRE prior to 8.00, because of the way certain internal optimizations were implemented in the pcre_exec() function, the PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be used with all patterns. From release 8.00 onwards, the restrictions no longer apply, and partial matching with can be requested for any pat- tern. Items that were formerly restricted were repeated single characters and repeated metasequences. If PCRE_PARTIAL was set for a pattern that did not conform to the restrictions, pcre_exec() returned the error code PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled pattern can be used for partial matching now always returns 1. EXAMPLE OF PARTIAL MATCHING USING PCRETEST If the escape sequence \P is present in a pcretest data line, the PCRE_PARTIAL_SOFT option is used for the match. Here is a run of pcretest that uses the date example quoted above: re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ data> 25jun04\P 0: 25jun04 1: jun data> 25dec3\P Partial match: 23dec3 data> 3ju\P Partial match: 3ju data> 3juj\P No match data> j\P No match The first data string is matched completely, so pcretest shows the matched substrings. The remaining four strings do not match the com- plete pattern, but the first two are partial matches. Similar output is obtained if DFA matching is used. If the escape sequence \P is present more than once in a pcretest data line, the PCRE_PARTIAL_HARD option is set for the match. MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec() When a partial match has been found using a DFA matching function, it is possible to continue the match by providing additional subject data and calling the function again with the same compiled regular expres- sion, this time setting the PCRE_DFA_RESTART option. You must pass the same working space as before, because this is where details of the pre- vious partial match are stored. Here is an example using pcretest, using the \R escape sequence to set the PCRE_DFA_RESTART option (\D specifies the use of the DFA matching function): re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ data> 23ja\P\D Partial match: 23ja data> n05\R\D 0: n05 The first call has "23ja" as the subject, and requests partial match- ing; the second call has "n05" as the subject for the continued (restarted) match. Notice that when the match is complete, only the last part is shown; PCRE does not retain the previously partially- matched string. It is up to the calling program to do that if it needs to. You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with PCRE_DFA_RESTART to continue partial matching over multiple segments. This facility can be used to pass very long subject strings to the DFA matching functions. MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec() From release 8.00, the standard matching functions can also be used to do multi-segment matching. Unlike the DFA functions, it is not possible to restart the previous match with a new segment of data. Instead, new data must be added to the previous subject string, and the entire match re-run, starting from the point where the partial match occurred. Ear- lier data can be discarded. It is best to use PCRE_PARTIAL_HARD in this situation, because it does not treat the end of a segment as the end of the subject when matching \z, \Z, \b, \B, and $. Consider an unanchored pattern that matches dates: re> /\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d/ data> The date is 23ja\P\P Partial match: 23ja At this stage, an application could discard the text preceding "23ja", add on text from the next segment, and call the matching function again. Unlike the DFA matching functions, the entire matching string must always be available, and the complete matching process occurs for each call, so more memory and more processing time is needed. Note: If the pattern contains lookbehind assertions, or \K, or starts with \b or \B, the string that is returned for a partial match includes characters that precede the partially matched string itself, because these must be retained when adding on more characters for a subsequent matching attempt. However, in some cases you may need to retain even earlier characters, as discussed in the next section. ISSUES WITH MULTI-SEGMENT MATCHING Certain types of pattern may give problems with multi-segment matching, whichever matching function is used. 1. If the pattern contains a test for the beginning of a line, you need to pass the PCRE_NOTBOL option when the subject string for any call does start at the beginning of a line. There is also a PCRE_NOTEOL option, but in practice when doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL. 2. Lookbehind assertions that have already been obeyed are catered for in the offsets that are returned for a partial match. However a lookbe- hind assertion later in the pattern could require even earlier charac- ters to be inspected. You can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the pcre_fullinfo() or pcre16_fullinfo() functions to obtain the length of the largest lookbe- hind in the pattern. This length is given in characters, not bytes. If you always retain at least that many characters before the partially matched string, all should be well. (Of course, near the start of the subject, fewer characters may be present; in that case all characters should be retained.) 3. Because a partial match must always contain at least one character, what might be considered a partial match of an empty string actually gives a "no match" result. For example: re> /c(?<=abc)x/ data> ab\P No match If the next segment begins "cx", a match should be found, but this will only happen if characters from the previous segment are retained. For this reason, a "no match" result should be interpreted as "partial match of an empty string" when the pattern contains lookbehinds. 4. Matching a subject string that is split into multiple segments may not always produce exactly the same result as matching over one single long string, especially when PCRE_PARTIAL_SOFT is used. The section "Partial Matching and Word Boundaries" above describes an issue that arises if the pattern ends with \b or \B. Another kind of difference may occur when there are multiple matching possibilities, because (for PCRE_PARTIAL_SOFT) a partial match result is given only when there are no completed matches. This means that as soon as the shortest match has been found, continuation to a new subject segment is no longer possi- ble. Consider again this pcretest example: re> /dog(sbody)?/ data> dogsb\P 0: dog data> do\P\D Partial match: do data> gsb\R\P\D 0: g data> dogsbody\D 0: dogsbody 1: dog The first data line passes the string "dogsb" to a standard matching function, setting the PCRE_PARTIAL_SOFT option. Although the string is a partial match for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter string "dog" is a complete match. Similarly, when the subject is presented to a DFA matching function in several parts ("do" and "gsb" being the first two) the match stops when "dog" has been found, and it is not possible to continue. On the other hand, if "dogsbody" is presented as a single string, a DFA matching function finds both matches. Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching multi-segment data. The example above then behaves differ- ently: re> /dog(sbody)?/ data> dogsb\P\P Partial match: dogsb data> do\P\D Partial match: do data> gsb\R\P\P\D Partial match: gsb 5. Patterns that contain alternatives at the top level which do not all start with the same pattern item may not work as expected when PCRE_DFA_RESTART is used. For example, consider this pattern: 1234|3789 If the first part of the subject is "ABC123", a partial match of the first alternative is found at offset 3. There is no partial match for the second alternative, because such a match does not start at the same point in the subject string. Attempting to continue with the string "7890" does not yield a match because only those alternatives that match at one point in the subject are remembered. The problem arises because the start of the second alternative matches within the first alternative. There is no problem with anchored patterns or patterns such as: 1234|ABCD where no string can be a partial match for both alternatives. This is not a problem if a standard matching function is used, because the entire match has to be rerun each time: re> /1234|3789/ data> ABC123\P\P Partial match: 123 data> 1237890 0: 3789 Of course, instead of using PCRE_DFA_RESTART, the same technique of re- running the entire match can also be used with the DFA matching func- tions. Another possibility is to work with two buffers. If a partial match at offset n in the first buffer is followed by "no match" when PCRE_DFA_RESTART is used on the second buffer, you can then try a new match starting at offset n+1 in the first buffer. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 24 February 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREPRECOMPILE(3) PCREPRECOMPILE(3) NAME PCRE - Perl-compatible regular expressions SAVING AND RE-USING PRECOMPILED PCRE PATTERNS If you are running an application that uses a large number of regular expression patterns, it may be useful to store them in a precompiled form instead of having to compile them every time the application is run. If you are not using any private character tables (see the pcre_maketables() documentation), this is relatively straightforward. If you are using private tables, it is a little bit more complicated. However, if you are using the just-in-time optimization feature, it is not possible to save and reload the JIT data. If you save compiled patterns to a file, you can copy them to a differ- ent host and run them there. If the two hosts have different endianness (byte order), you should run the pcre[16]_pattern_to_host_byte_order() function on the new host before trying to match the pattern. The match- ing functions return PCRE_ERROR_BADENDIANNESS if they detect a pattern with the wrong endianness. Compiling regular expressions with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes, and saving and restoring a compiled pattern loses any JIT optimization data. SAVING A COMPILED PATTERN The value returned by pcre[16]_compile() points to a single block of memory that holds the compiled pattern and associated data. You can find the length of this block in bytes by calling pcre[16]_fullinfo() with an argument of PCRE_INFO_SIZE. You can then save the data in any appropriate manner. Here is sample code for the 8-bit library that com- piles a pattern and writes it to a file. It assumes that the variable fd refers to a file that is open for output: int erroroffset, rc, size; char *error; pcre *re; re = pcre_compile("my pattern", 0, &error, &erroroffset, NULL); if (re == NULL) { ... handle errors ... } rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); if (rc < 0) { ... handle errors ... } rc = fwrite(re, 1, size, fd); if (rc != size) { ... handle errors ... } In this example, the bytes that comprise the compiled pattern are copied exactly. Note that this is binary data that may contain any of the 256 possible byte values. On systems that make a distinction between binary and non-binary data, be sure that the file is opened for binary output. If you want to write more than one pattern to a file, you will have to devise a way of separating them. For binary data, preceding each pat- tern with its length is probably the most straightforward approach. Another possibility is to write out the data in hexadecimal instead of binary, one pattern to a line. Saving compiled patterns in a file is only one possible way of storing them for later use. They could equally well be saved in a database, or in the memory of some daemon process that passes them via sockets to the processes that want them. If the pattern has been studied, it is also possible to save the normal study data in a similar way to the compiled pattern itself. However, if the PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is cre- ated cannot be saved because it is too dependent on the current envi- ronment. When studying generates additional information, pcre[16]_study() returns a pointer to a pcre[16]_extra data block. Its format is defined in the section on matching a pattern in the pcreapi documentation. The study_data field points to the binary study data, and this is what you must save (not the pcre[16]_extra block itself). The length of the study data can be obtained by calling pcre[16]_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. Remember to check that pcre[16]_study() did return a non-NULL value before try- ing to save the study data. RE-USING A PRECOMPILED PATTERN Re-using a precompiled pattern is straightforward. Having reloaded it into main memory, called pcre[16]_pattern_to_host_byte_order() if nec- essary, you pass its pointer to pcre[16]_exec() or pcre[16]_dfa_exec() in the usual way. However, if you passed a pointer to custom character tables when the pattern was compiled (the tableptr argument of pcre[16]_compile()), you must now pass a similar pointer to pcre[16]_exec() or pcre[16]_dfa_exec(), because the value saved with the compiled pattern will obviously be nonsense. A field in a pcre[16]_extra() block is used to pass this data, as described in the section on matching a pattern in the pcreapi documentation. If you did not provide custom character tables when the pattern was compiled, the pointer in the compiled pattern is NULL, which causes the matching functions to use PCRE's internal tables. Thus, you do not need to take any special action at run time in this case. If you saved study data with the compiled pattern, you need to create your own pcre[16]_extra data block and set the study_data field to point to the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA bit in the flags field to indicate that study data is present. Then pass the pcre[16]_extra block to the matching function in the usual way. If the pattern was studied for just-in-time optimization, that data cannot be saved, and so is lost by a save/restore cycle. COMPATIBILITY WITH DIFFERENT PCRE RELEASES In general, it is safest to recompile all saved patterns when you update to a new PCRE release, though not all updates actually require this. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREPERFORM(3) PCREPERFORM(3) NAME PCRE - Perl-compatible regular expressions PCRE PERFORMANCE Two aspects of performance are discussed below: memory usage and pro- cessing time. The way you express your pattern as a regular expression can affect both of them. COMPILED PATTERN MEMORY USAGE Patterns are compiled by PCRE into a reasonably efficient interpretive code, so that most simple patterns do not use much memory. However, there is one case where the memory usage of a compiled pattern can be unexpectedly large. If a parenthesized subpattern has a quantifier with a minimum greater than 1 and/or a limited maximum, the whole subpattern is repeated in the compiled code. For example, the pattern (abc|def){2,4} is compiled as if it were (abc|def)(abc|def)((abc|def)(abc|def)?)? (Technical aside: It is done this way so that backtrack points within each of the repetitions can be independently maintained.) For regular expressions whose quantifiers use only small numbers, this is not usually a problem. However, if the numbers are large, and par- ticularly if such repetitions are nested, the memory usage can become an embarrassment. For example, the very simple pattern ((ab){1,1000}c){1,3} uses 51K bytes when compiled using the 8-bit library. When PCRE is com- piled with its default internal pointer size of two bytes, the size limit on a compiled pattern is 64K data units, and this is reached with the above pattern if the outer repetition is increased from 3 to 4. PCRE can be compiled to use larger internal pointers and thus handle larger compiled patterns, but it is better to try to rewrite your pat- tern to use less memory if you can. One way of reducing the memory usage for such patterns is to make use of PCRE's "subroutine" facility. Re-writing the above pattern as ((ab)(?2){0,999}c)(?1){0,2} reduces the memory requirements to 18K, and indeed it remains under 20K even with the outer repetition increased to 100. However, this pattern is not exactly equivalent, because the "subroutine" calls are treated as atomic groups into which there can be no backtracking if there is a subsequent matching failure. Therefore, PCRE cannot do this kind of rewriting automatically. Furthermore, there is a noticeable loss of speed when executing the modified pattern. Nevertheless, if the atomic grouping is not a problem and the loss of speed is acceptable, this kind of rewriting will allow you to process patterns that PCRE cannot otherwise handle. STACK USAGE AT RUN TIME When pcre_exec() or pcre16_exec() is used for matching, certain kinds of pattern can cause it to use large amounts of the process stack. In some environments the default process stack is quite small, and if it runs out the result is often SIGSEGV. This issue is probably the most frequently raised problem with PCRE. Rewriting your pattern can often help. The pcrestack documentation discusses this issue in detail. PROCESSING TIME Certain items in regular expression patterns are processed more effi- ciently than others. It is more efficient to use a character class like [aeiou] than a set of single-character alternatives such as (a|e|i|o|u). In general, the simplest construction that provides the required behaviour is usually the most efficient. Jeffrey Friedl's book contains a lot of useful general discussion about optimizing regular expressions for efficient performance. This document contains a few observations about PCRE. Using Unicode character properties (the \p, \P, and \X escapes) is slow, because PCRE has to scan a structure that contains data for over fifteen thousand characters whenever it needs a character's property. If you can find an alternative pattern that does not use character properties, it will probably be faster. By default, the escape sequences \b, \d, \s, and \w, and the POSIX character classes such as [:alpha:] do not use Unicode properties, partly for backwards compatibility, and partly for performance reasons. However, you can set PCRE_UCP if you want Unicode character properties to be used. This can double the matching time for items such as \d, when matched with a traditional matching function; the performance loss is less with a DFA matching function, and in both cases there is not much difference for \b. When a pattern begins with .* not in parentheses, or in parentheses that are not the subject of a backreference, and the PCRE_DOTALL option is set, the pattern is implicitly anchored by PCRE, since it can match only at the start of a subject string. However, if PCRE_DOTALL is not set, PCRE cannot make this optimization, because the . metacharacter does not then match a newline, and if the subject string contains new- lines, the pattern may match from the character immediately following one of them instead of from the very start. For example, the pattern .*second matches the subject "first\nand second" (where \n stands for a newline character), with the match starting at the seventh character. In order to do this, PCRE has to retry the match starting after every newline in the subject. If you are using such a pattern with subject strings that do not con- tain newlines, the best performance is obtained by setting PCRE_DOTALL, or starting the pattern with ^.* or ^.*? to indicate explicit anchor- ing. That saves PCRE from having to scan along the subject looking for a newline to restart at. Beware of patterns that contain nested indefinite repeats. These can take a long time to run when applied to a string that does not match. Consider the pattern fragment ^(a+)* This can match "aaaa" in 16 different ways, and this number increases very rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4 times, and for each of those cases other than 0 or 4, the + repeats can match different numbers of times.) When the remainder of the pattern is such that the entire match is going to fail, PCRE has in principle to try every possible variation, and this can take an extremely long time, even for relatively short strings. An optimization catches some of the more simple cases such as (a+)*b where a literal character follows. Before embarking on the standard matching procedure, PCRE checks that there is a "b" later in the sub- ject string, and if there is not, it fails the match immediately. How- ever, when there is no following literal this optimization cannot be used. You can see the difference by comparing the behaviour of (a+)*\d with the pattern above. The former gives a failure almost instantly when applied to a whole line of "a" characters, whereas the latter takes an appreciable time with strings longer than about 20 characters. In many cases, the solution to this kind of performance issue is to use an atomic group or a possessive quantifier. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 09 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCREPOSIX(3) PCREPOSIX(3) NAME PCRE - Perl-compatible regular expressions. SYNOPSIS OF POSIX API #include int regcomp(regex_t *preg, const char *pattern, int cflags); int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); void regfree(regex_t *preg); DESCRIPTION This set of functions provides a POSIX-style API for the PCRE regular expression 8-bit library. See the pcreapi documentation for a descrip- tion of PCRE's native API, which contains much additional functional- ity. There is no POSIX-style wrapper for PCRE's 16-bit library. The functions described here are just wrapper functions that ultimately call the PCRE native API. Their prototypes are defined in the pcreposix.h header file, and on Unix systems the library itself is called pcreposix.a, so can be accessed by adding -lpcreposix to the command for linking an application that uses them. Because the POSIX functions call the native ones, it is also necessary to add -lpcre. I have implemented only those POSIX option bits that can be reasonably mapped to PCRE native options. In addition, the option REG_EXTENDED is defined with the value zero. This has no effect, but since programs that are written to the POSIX interface often use it, this makes it easier to slot in PCRE as a replacement library. Other POSIX options are not even defined. There are also some other options that are not defined by POSIX. These have been added at the request of users who want to make use of certain PCRE-specific features via the POSIX calling interface. When PCRE is called via these functions, it is only the API that is POSIX-like in style. The syntax and semantics of the regular expres- sions themselves are still those of Perl, subject to the setting of various PCRE options, as described below. "POSIX-like in style" means that the API approximates to the POSIX definition; it is not fully POSIX-compatible, and in multi-byte encoding domains it is probably even less compatible. The header for these functions is supplied as pcreposix.h to avoid any potential clash with other POSIX libraries. It can, of course, be renamed or aliased as regex.h, which is the "correct" name. It provides two structure types, regex_t for compiled internal forms, and reg- match_t for returning captured substrings. It also defines some con- stants whose names start with "REG_"; these are used for setting options and identifying error codes. COMPILING A PATTERN The function regcomp() is called to compile a pattern into an internal form. The pattern is a C string terminated by a binary zero, and is passed in the argument pattern. The preg argument is a pointer to a regex_t structure that is used as a base for storing information about the compiled regular expression. The argument cflags is either zero, or contains one or more of the bits defined by the following macros: REG_DOTALL The PCRE_DOTALL option is set when the regular expression is passed for compilation to the native function. Note that REG_DOTALL is not part of the POSIX standard. REG_ICASE The PCRE_CASELESS option is set when the regular expression is passed for compilation to the native function. REG_NEWLINE The PCRE_MULTILINE option is set when the regular expression is passed for compilation to the native function. Note that this does not mimic the defined POSIX behaviour for REG_NEWLINE (see the following sec- tion). REG_NOSUB The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is passed for compilation to the native function. In addition, when a pat- tern that is compiled with this flag is passed to regexec() for match- ing, the nmatch and pmatch arguments are ignored, and no captured strings are returned. REG_UCP The PCRE_UCP option is set when the regular expression is passed for compilation to the native function. This causes PCRE to use Unicode properties when matchine \d, \w, etc., instead of just recognizing ASCII values. Note that REG_UTF8 is not part of the POSIX standard. REG_UNGREEDY The PCRE_UNGREEDY option is set when the regular expression is passed for compilation to the native function. Note that REG_UNGREEDY is not part of the POSIX standard. REG_UTF8 The PCRE_UTF8 option is set when the regular expression is passed for compilation to the native function. This causes the pattern itself and all data strings used for matching it to be treated as UTF-8 strings. Note that REG_UTF8 is not part of the POSIX standard. In the absence of these flags, no options are passed to the native function. This means the the regex is compiled with PCRE default semantics. In particular, the way it handles newline characters in the subject string is the Perl way, not the POSIX way. Note that setting PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE. It does not affect the way newlines are matched by . (they are not) or by a negative class such as [^a] (they are). The yield of regcomp() is zero on success, and non-zero otherwise. The preg structure is filled in on success, and one member of the structure is public: re_nsub contains the number of capturing subpatterns in the regular expression. Various error codes are defined in the header file. NOTE: If the yield of regcomp() is non-zero, you must not attempt to use the contents of the preg structure. If, for example, you pass it to regexec(), the result is undefined and your program is likely to crash. MATCHING NEWLINE CHARACTERS This area is not simple, because POSIX and Perl take different views of things. It is not possible to get PCRE to obey POSIX semantics, but then PCRE was never intended to be a POSIX engine. The following table lists the different possibilities for matching newline characters in PCRE: Default Change with . matches newline no PCRE_DOTALL newline matches [^a] yes not changeable $ matches \n at end yes PCRE_DOLLARENDONLY $ matches \n in middle no PCRE_MULTILINE ^ matches \n in middle no PCRE_MULTILINE This is the equivalent table for POSIX: Default Change with . matches newline yes REG_NEWLINE newline matches [^a] yes REG_NEWLINE $ matches \n at end no REG_NEWLINE $ matches \n in middle no REG_NEWLINE ^ matches \n in middle no REG_NEWLINE PCRE's behaviour is the same as Perl's, except that there is no equiva- lent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is no way to stop newline from matching [^a]. The default POSIX newline handling can be obtained by setting PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE behave exactly as for the REG_NEWLINE action. MATCHING A PATTERN The function regexec() is called to match a compiled pattern preg against a given string, which is by default terminated by a zero byte (but see REG_STARTEND below), subject to the options in eflags. These can be: REG_NOTBOL The PCRE_NOTBOL option is set when calling the underlying PCRE matching function. REG_NOTEMPTY The PCRE_NOTEMPTY option is set when calling the underlying PCRE match- ing function. Note that REG_NOTEMPTY is not part of the POSIX standard. However, setting this option can give more POSIX-like behaviour in some situations. REG_NOTEOL The PCRE_NOTEOL option is set when calling the underlying PCRE matching function. REG_STARTEND The string is considered to start at string + pmatch[0].rm_so and to have a terminating NUL located at string + pmatch[0].rm_eo (there need not actually be a NUL at that location), regardless of the value of nmatch. This is a BSD extension, compatible with but not specified by IEEE Standard 1003.2 (POSIX.2), and should be used with caution in software intended to be portable to other systems. Note that a non-zero rm_so does not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not how it is matched. If the pattern was compiled with the REG_NOSUB flag, no data about any matched strings is returned. The nmatch and pmatch arguments of regexec() are ignored. If the value of nmatch is zero, or if the value pmatch is NULL, no data about any matched strings is returned. Otherwise,the portion of the string that was matched, and also any cap- tured substrings, are returned via the pmatch argument, which points to an array of nmatch structures of type regmatch_t, containing the mem- bers rm_so and rm_eo. These contain the offset to the first character of each substring and the offset to the first character after the end of each substring, respectively. The 0th element of the vector relates to the entire portion of string that was matched; subsequent elements relate to the capturing subpatterns of the regular expression. Unused entries in the array have both structure members set to -1. A successful match yields a zero return; various error codes are defined in the header file, of which REG_NOMATCH is the "expected" failure code. ERROR MESSAGES The regerror() function maps a non-zero errorcode from either regcomp() or regexec() to a printable message. If preg is not NULL, the error should have arisen from the use of that structure. A message terminated by a binary zero is placed in errbuf. The length of the message, including the zero, is limited to errbuf_size. The yield of the func- tion is the size of buffer needed to hold the whole message. MEMORY USAGE Compiling a regular expression causes memory to be allocated and asso- ciated with the preg structure. The function regfree() frees all such memory, after which preg may no longer be used as a compiled expres- sion. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 09 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCRECPP(3) PCRECPP(3) NAME PCRE - Perl-compatible regular expressions. SYNOPSIS OF C++ WRAPPER #include DESCRIPTION The C++ wrapper for PCRE was provided by Google Inc. Some additional functionality was added by Giuseppe Maxia. This brief man page was con- structed from the notes in the pcrecpp.h file, which should be con- sulted for further details. Note that the C++ wrapper supports only the original 8-bit PCRE library. There is no 16-bit support at present. MATCHING INTERFACE The "FullMatch" operation checks that supplied text matches a supplied pattern exactly. If pointer arguments are supplied, it copies matched sub-strings that match sub-patterns into them. Example: successful match pcrecpp::RE re("h.*o"); re.FullMatch("hello"); Example: unsuccessful match (requires full match): pcrecpp::RE re("e"); !re.FullMatch("hello"); Example: creating a temporary RE object: pcrecpp::RE("h.*o").FullMatch("hello"); You can pass in a "const char*" or a "string" for "text". The examples below tend to use a const char*. You can, as in the different examples above, store the RE object explicitly in a variable or use a temporary RE object. The examples below use one mode or the other arbitrarily. Either could correctly be used for any of these examples. You must supply extra pointer arguments to extract matched subpieces. Example: extracts "ruby" into "s" and 1234 into "i" int i; string s; pcrecpp::RE re("(\\w+):(\\d+)"); re.FullMatch("ruby:1234", &s, &i); Example: does not try to extract any extra sub-patterns re.FullMatch("ruby:1234", &s); Example: does not try to extract into NULL re.FullMatch("ruby:1234", NULL, &i); Example: integer overflow causes failure !re.FullMatch("ruby:1234567891234", NULL, &i); Example: fails because there aren't enough sub-patterns: !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s); Example: fails because string cannot be stored in integer !pcrecpp::RE("(.*)").FullMatch("ruby", &i); The provided pointer arguments can be pointers to any scalar numeric type, or one of: string (matched piece is copied to string) StringPiece (StringPiece is mutated to point to matched piece) T (where "bool T::ParseFrom(const char*, int)" exists) NULL (the corresponding matched sub-pattern is not copied) The function returns true iff all of the following conditions are sat- isfied: a. "text" matches "pattern" exactly; b. The number of matched sub-patterns is >= number of supplied pointers; c. The "i"th argument has a suitable type for holding the string captured as the "i"th sub-pattern. If you pass in void * NULL for the "i"th argument, or a non-void * NULL of the correct type, or pass fewer arguments than the number of sub-patterns, "i"th captured sub-pattern is ignored. CAVEAT: An optional sub-pattern that does not exist in the matched string is assigned the empty string. Therefore, the following will return false (because the empty string is not a valid number): int number; pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number); The matching interface supports at most 16 arguments per call. If you need more, consider using the more general interface pcrecpp::RE::DoMatch. See pcrecpp.h for the signature for DoMatch. NOTE: Do not use no_arg, which is used internally to mark the end of a list of optional arguments, as a placeholder for missing arguments, as this can lead to segfaults. QUOTING METACHARACTERS You can use the "QuoteMeta" operation to insert backslashes before all potentially meaningful characters in a string. The returned string, used as a regular expression, will exactly match the original string. Example: string quoted = RE::QuoteMeta(unquoted); Note that it's legal to escape a character even if it has no special meaning in a regular expression -- so this function does that. (This also makes it identical to the perl function of the same name; see "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes "1\.5\-2\.0\?". PARTIAL MATCHES You can use the "PartialMatch" operation when you want the pattern to match any substring of the text. Example: simple search for a string: pcrecpp::RE("ell").PartialMatch("hello"); Example: find first number in a string: int number; pcrecpp::RE re("(\\d+)"); re.PartialMatch("x*100 + 20", &number); assert(number == 100); UTF-8 AND THE MATCHING INTERFACE By default, pattern and text are plain text, one byte per character. The UTF8 flag, passed to the constructor, causes both pattern and string to be treated as UTF-8 text, still a byte stream but potentially multiple bytes per character. In practice, the text is likelier to be UTF-8 than the pattern, but the match returned may depend on the UTF8 flag, so always use it when matching UTF8 text. For example, "." will match one byte normally but with UTF8 set may match up to three bytes of a multi-byte character. Example: pcrecpp::RE_Options options; options.set_utf8(); pcrecpp::RE re(utf8_pattern, options); re.FullMatch(utf8_string); Example: using the convenience function UTF8(): pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); re.FullMatch(utf8_string); NOTE: The UTF8 flag is ignored if pcre was not configured with the --enable-utf8 flag. PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE PCRE defines some modifiers to change the behavior of the regular expression engine. The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle to pass such modifiers to a RE class. Cur- rently, the following modifiers are supported: modifier description Perl corresponding PCRE_CASELESS case insensitive match /i PCRE_MULTILINE multiple lines match /m PCRE_DOTALL dot matches newlines /s PCRE_DOLLAR_ENDONLY $ matches only at end N/A PCRE_EXTRA strict escape parsing N/A PCRE_EXTENDED ignore white spaces /x PCRE_UTF8 handles UTF8 chars built-in PCRE_UNGREEDY reverses * and *? N/A PCRE_NO_AUTO_CAPTURE disables capturing parens N/A (*) (*) Both Perl and PCRE allow non capturing parentheses by means of the "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not cap- ture, while (ab|cd) does. For a full account on how each modifier works, please check the PCRE API reference page. For each modifier, there are two member functions whose name is made out of the modifier in lowercase, without the "PCRE_" prefix. For instance, PCRE_CASELESS is handled by bool caseless() which returns true if the modifier is set, and RE_Options & set_caseless(bool) which sets or unsets the modifier. Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the set_match_limit() and match_limit() member functions. Setting match_limit to a non-zero value will limit the exe- cution of pcre to keep it from doing bad things like blowing the stack or taking an eternity to return a result. A value of 5000 is good enough to stop stack blowup in a 2MB thread stack. Setting match_limit to zero disables match limiting. Alternatively, you can call match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much PCRE recurses. match_limit() limits the number of matches PCRE does; match_limit_recursion() limits the depth of internal recursion, and therefore the amount of stack that is used. Normally, to pass one or more modifiers to a RE class, you declare a RE_Options object, set the appropriate options, and pass this object to a RE constructor. Example: RE_Options opt; opt.set_caseless(true); if (RE("HELLO", opt).PartialMatch("hello world")) ... RE_options has two constructors. The default constructor takes no argu- ments and creates a set of flags that are off by default. The optional parameter option_flags is to facilitate transfer of legacy code from C programs. This lets you do RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); However, new code is better off doing RE(pattern, RE_Options().set_caseless(true).set_multiline(true)) .PartialMatch(str); If you are going to pass one of the most used modifiers, there are some convenience functions that return a RE_Options class with the appropri- ate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(), and EXTENDED(). If you need to set several options at once, and you don't want to go through the pains of declaring a RE_Options object and setting several options, there is a parallel method that give you such ability on the fly. You can concatenate several set_xxxxx() member functions, since each of them returns a reference to its class object. For example, to pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one statement, you may write: RE(" ^ xyz \\s+ .* blah$", RE_Options() .set_caseless(true) .set_extended(true) .set_multiline(true)).PartialMatch(sometext); SCANNING TEXT INCREMENTALLY The "Consume" operation may be useful if you want to repeatedly match regular expressions at the front of a string and skip over them as they match. This requires use of the "StringPiece" type, which represents a sub-range of a real string. Like RE, StringPiece is defined in the pcrecpp namespace. Example: read lines of the form "var = value" from a string. string contents = ...; // Fill string somehow pcrecpp::StringPiece input(contents); // Wrap in a StringPiece string var; int value; pcrecpp::RE re("(\\w+) = (\\d+)\n"); while (re.Consume(&input, &var, &value)) { ...; } Each successful call to "Consume" will set "var/value", and also advance "input" so it points past the matched text. The "FindAndConsume" operation is similar to "Consume" but does not anchor your match at the beginning of the string. For example, you could extract all words from a string by repeatedly calling pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) PARSING HEX/OCTAL/C-RADIX NUMBERS By default, if you pass a pointer to a numeric value, the corresponding text is interpreted as a base-10 number. You can instead wrap the pointer with a call to one of the operators Hex(), Octal(), or CRadix() to interpret the text in another base. The CRadix operator interprets C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to base-10. Example: int a, b, c, d; pcrecpp::RE re("(.*) (.*) (.*) (.*)"); re.FullMatch("100 40 0100 0x40", pcrecpp::Octal(&a), pcrecpp::Hex(&b), pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); will leave 64 in a, b, c, and d. REPLACING PARTS OF STRINGS You can replace the first match of "pattern" in "str" with "rewrite". Within "rewrite", backslash-escaped digits (\1 to \9) can be used to insert text matching corresponding parenthesized group from the pat- tern. \0 in "rewrite" refers to the entire matching text. For example: string s = "yabba dabba doo"; pcrecpp::RE("b+").Replace("d", &s); will leave "s" containing "yada dabba doo". The result is true if the pattern matches and a replacement occurs, false otherwise. GlobalReplace is like Replace except that it replaces all occurrences of the pattern in the string with the rewrite. Replacements are not subject to re-matching. For example: string s = "yabba dabba doo"; pcrecpp::RE("b+").GlobalReplace("d", &s); will leave "s" containing "yada dada doo". It returns the number of replacements made. Extract is like Replace, except that if the pattern matches, "rewrite" is copied into "out" (an additional argument) with substitutions. The non-matching portions of "text" are ignored. Returns true iff a match occurred and the extraction happened successfully; if no match occurs, the string is left unaffected. AUTHOR The C++ wrapper was contributed by Google Inc. Copyright (c) 2007 Google Inc. REVISION Last updated: 08 January 2012 ------------------------------------------------------------------------------ PCRESAMPLE(3) PCRESAMPLE(3) NAME PCRE - Perl-compatible regular expressions PCRE SAMPLE PROGRAM A simple, complete demonstration program, to get you started with using PCRE, is supplied in the file pcredemo.c in the PCRE distribution. A listing of this program is given in the pcredemo documentation. If you do not have a copy of the PCRE distribution, you can save this listing to re-create pcredemo.c. The demonstration program, which uses the original PCRE 8-bit library, compiles the regular expression that is its first argument, and matches it against the subject string in its second argument. No PCRE options are set, and default character tables are used. If matching succeeds, the program outputs the portion of the subject that matched, together with the contents of any captured substrings. If the -g option is given on the command line, the program then goes on to check for further matches of the same regular expression in the same subject string. The logic is a little bit tricky because of the possi- bility of matching an empty string. Comments in the code explain what is going on. If PCRE is installed in the standard include and library directories for your operating system, you should be able to compile the demonstra- tion program using this command: gcc -o pcredemo pcredemo.c -lpcre If PCRE is installed elsewhere, you may need to add additional options to the command line. For example, on a Unix-like system that has PCRE installed in /usr/local, you can compile the demonstration program using a command like this: gcc -o pcredemo -I/usr/local/include pcredemo.c \ -L/usr/local/lib -lpcre In a Windows environment, if you want to statically link the program against a non-dll pcre.a file, you must uncomment the line that defines PCRE_STATIC before including pcre.h, because otherwise the pcre_mal- loc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. Once you have compiled and linked the demonstration program, you can run simple tests like this: ./pcredemo 'cat|dog' 'the cat sat on the mat' ./pcredemo -g 'cat|dog' 'the dog sat on the cat' Note that there is a much more comprehensive test program, called pcretest, which supports many more facilities for testing regular expressions and both PCRE libraries. The pcredemo program is provided as a simple coding example. If you try to run pcredemo when PCRE is not installed in the standard library directory, you may get an error like this on some operating systems (e.g. Solaris): ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or directory This is caused by the way shared library support works on those sys- tems. You need to add -R/usr/local/lib (for example) to the compile command to get round this problem. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCRELIMITS(3) PCRELIMITS(3) NAME PCRE - Perl-compatible regular expressions SIZE AND OTHER LIMITATIONS There are some size limitations in PCRE but it is hoped that they will never in practice be relevant. The maximum length of a compiled pattern is approximately 64K data units (bytes for the 8-bit library, 16-bit units for the 16-bit library) if PCRE is compiled with the default internal linkage size of 2 bytes. If you want to process regular expressions that are truly enormous, you can compile PCRE with an internal linkage size of 3 or 4 (when building the 16-bit library, 3 is rounded up to 4). See the README file in the source distribution and the pcrebuild documentation for details. In these cases the limit is substantially larger. How- ever, the speed of execution is slower. All values in repeating quantifiers must be less than 65536. There is no limit to the number of parenthesized subpatterns, but there can be no more than 65535 capturing subpatterns. There is a limit to the number of forward references to subsequent sub- patterns of around 200,000. Repeated forward references with fixed upper limits, for example, (?2){0,100} when subpattern number 2 is to the right, are included in the count. There is no limit to the number of backward references. The maximum length of name for a named subpattern is 32 characters, and the maximum number of named subpatterns is 10000. The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit library. 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. AUTHOR Philip Hazel University Computing Service Cambridge CB2 3QH, England. REVISION Last updated: 04 May 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ PCRESTACK(3) PCRESTACK(3) NAME PCRE - Perl-compatible regular expressions PCRE DISCUSSION OF STACK USAGE When you call pcre[16]_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 proceeds deeper and deeper into the tree of possibilities, the recursion depth increases. The match() function is also called in other circumstances, for example, whenever a parenthesized sub-pattern is entered, and in certain cases of repetition. 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 above comments apply when pcre[16]_exec() is run in its normal interpretive manner. If the pattern was studied with the PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was success- ful, and the options passed to pcre[16]_exec() were not incompatible, the matching process uses the JIT-compiled code instead of the match() function. In this case, the memory requirements are handled entirely differently. See the pcrejit documentation for details. The pcre[16]_dfa_exec() function operates in an entirely different way, and uses recursion only when there is a regular expression recursion or subroutine call in the pattern. This includes the processing of asser- tion and "once-only" subpatterns, which are handled like subroutine calls. Normally, these are never very deep, and the limit on the com- plexity of pcre[16]_dfa_exec() is controlled by the amount of workspace it is given. However, it is possible to write patterns with runaway infinite recursions; such patterns will cause pcre[16]_dfa_exec() to run out of stack. At present, there is no protection against this. The comments that follow do NOT apply to pcre[16]_dfa_exec(); they are relevant only for pcre[16]_exec() without the JIT optimization. Reducing pcre[16]_exec()'s stack usage 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 " .PP .SM .B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); .PP .B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP); . .SH DESCRIPTION .rs .sp This function makes it possible for a client program to find out which optional features are available in the version of the PCRE library it is using. The arguments are as follows: .sp \fIwhat\fP A code specifying what information is required \fIwhere\fP Points to where to put the data .sp The \fIwhere\fP argument must point to an integer variable, except for PCRE_CONFIG_MATCH_LIMIT and PCRE_CONFIG_MATCH_LIMIT_RECURSION, when it must point to an unsigned long integer. The available codes are: .sp PCRE_CONFIG_JIT Availability of just-in-time compiler support (1=yes 0=no) PCRE_CONFIG_JITTARGET String containing information about the target architecture for the JIT compiler, or NULL if there is no JIT support PCRE_CONFIG_LINK_SIZE Internal link size: 2, 3, or 4 PCRE_CONFIG_MATCH_LIMIT Internal resource limit PCRE_CONFIG_MATCH_LIMIT_RECURSION Internal recursion depth limit PCRE_CONFIG_NEWLINE Value of the default newline sequence: 13 (0x000d) for CR 10 (0x000a) for LF 3338 (0x0d0a) for CRLF -2 for ANYCRLF -1 for ANY PCRE_CONFIG_BSR Indicates what \eR matches by default: 0 all Unicode line endings 1 CR, LF, or CRLF only PCRE_CONFIG_POSIX_MALLOC_THRESHOLD Threshold of return slots, above which \fBmalloc()\fP is used by the POSIX API PCRE_CONFIG_STACKRECURSE Recursion implementation (1=stack 0=heap) PCRE_CONFIG_UTF16 Availability of UTF-16 support (1=yes 0=no); option for \fBpcre16_config()\fP PCRE_CONFIG_UTF8 Availability of UTF-8 support (1=yes 0=no); option for \fBpcre_config()\fP PCRE_CONFIG_UNICODE_PROPERTIES Availability of Unicode property support (1=yes 0=no) .sp The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. That error is also given if PCRE_CONFIG_UTF16 is passed to \fBpcre_config()\fP or if PCRE_CONFIG_UTF8 is passed to \fBpcre16_config()\fP. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_jit_stack_free.30000644000222100022210000000123111735631542014125 00000000000000.TH PCRE_JIT_STACK_FREE 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B void pcre_jit_stack_free(pcre_jit_stack *\fIstack\fP); .PP .B void pcre16_jit_stack_free(pcre16_jit_stack *\fIstack\fP); . .SH DESCRIPTION .rs .sp This function is used to free a JIT stack that was created by \fBpcre[16]_jit_stack_alloc()\fP when it is no longer needed. For more details, see the .\" HREF \fBpcrejit\fP .\" page. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_get_stringnumber.30000644000222100022210000000214211735631416014531 00000000000000.TH PCRE_GET_STRINGNUMBER 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_get_stringnumber(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP); .PP .B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIname\fP); . .SH DESCRIPTION .rs .sp This convenience function finds the number of a named substring capturing parenthesis in a compiled pattern. Its arguments are: .sp \fIcode\fP Compiled regular expression \fIname\fP Name whose number is required .sp The yield of the function is the number of the parenthesis if the name is found, or PCRE_ERROR_NOSUBSTRING otherwise. When duplicate names are allowed (PCRE_DUPNAMES is set), it is not defined which of the numbers is returned by \fBpcre[16]_get_stringnumber()\fP. You can obtain the complete list by calling \fBpcre[16]_get_stringtable_entries()\fP. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_compile2.30000644000222100022210000000715611760163326012675 00000000000000.TH PCRE_COMPILE2 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B pcre *pcre_compile2(const char *\fIpattern\fP, int \fIoptions\fP, .ti +5n .B int *\fIerrorcodeptr\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); .PP .B pcre16 *pcre16_compile2(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, .ti +5n .B int *\fIerrorcodeptr\fP, .ti +5n .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); . .SH DESCRIPTION .rs .sp This function compiles a regular expression into an internal form. It is the same as \fBpcre[16]_compile()\fP, except for the addition of the \fIerrorcodeptr\fP argument. The arguments are: . .sp \fIpattern\fP A zero-terminated string containing the regular expression to be compiled \fIoptions\fP Zero or more option bits \fIerrorcodeptr\fP Where to put an error code \fIerrptr\fP Where to put an error message \fIerroffset\fP Offset in pattern where error was found \fItableptr\fP Pointer to character tables, or NULL to use the built-in default .sp The option bits are: .sp PCRE_ANCHORED Force pattern anchoring PCRE_AUTO_CALLOUT Compile automatic callouts PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF PCRE_BSR_UNICODE \eR matches all Unicode line endings PCRE_CASELESS Do caseless matching PCRE_DOLLAR_ENDONLY $ not to match newline at end PCRE_DOTALL . matches anything including NL PCRE_DUPNAMES Allow duplicate names for subpatterns PCRE_EXTENDED Ignore white space and # comments PCRE_EXTRA PCRE extra features (not much use currently) PCRE_FIRSTLINE Force matching to be before newline PCRE_JAVASCRIPT_COMPAT JavaScript compatibility PCRE_MULTILINE ^ and $ match newlines within data PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline sequences PCRE_NEWLINE_CR Set CR as the newline sequence PCRE_NEWLINE_CRLF Set CRLF as the newline sequence PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 validity (only relevant if PCRE_UTF16 is set) PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) PCRE_UCP Use Unicode properties for \ed, \ew, etc. PCRE_UNGREEDY Invert greediness of quantifiers PCRE_UTF16 Run \fBpcre16_compile()\fP in UTF-16 mode PCRE_UTF8 Run \fBpcre_compile()\fP in UTF-8 mode .sp PCRE must be built with UTF support in order to use PCRE_UTF8/16 and PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used. .P The yield of the function is a pointer to a private data structure that contains the compiled pattern, or NULL if an error was detected. Note that compiling regular expressions with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcrelimits.30000644000222100022210000000432511750751556012327 00000000000000.TH PCRELIMITS 3 "04 May 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "SIZE AND OTHER LIMITATIONS" .rs .sp There are some size limitations in PCRE but it is hoped that they will never in practice be relevant. .P The maximum length of a compiled pattern is approximately 64K data units (bytes for the 8-bit library, 16-bit units for the 16-bit library) if PCRE is compiled with the default internal linkage size of 2 bytes. If you want to process regular expressions that are truly enormous, you can compile PCRE with an internal linkage size of 3 or 4 (when building the 16-bit library, 3 is rounded up to 4). See the \fBREADME\fP file in the source distribution and the .\" HREF \fBpcrebuild\fP .\" documentation for details. In these cases the limit is substantially larger. However, the speed of execution is slower. .P All values in repeating quantifiers must be less than 65536. .P There is no limit to the number of parenthesized subpatterns, but there can be no more than 65535 capturing subpatterns. .P There is a limit to the number of forward references to subsequent subpatterns of around 200,000. Repeated forward references with fixed upper limits, for example, (?2){0,100} when subpattern number 2 is to the right, are included in the count. There is no limit to the number of backward references. .P The maximum length of name for a named subpattern is 32 characters, and the maximum number of named subpatterns is 10000. .P The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit library. .P 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 indefinite 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 .\" HREF \fBpcrestack\fP .\" documentation. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 04 May 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_get_stringtable_entries.30000644000222100022210000000247111735631440016063 00000000000000.TH PCRE_GET_STRINGTABLE_ENTRIES 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_get_stringtable_entries(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP); .PP .B int pcre16_get_stringtable_entries(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP); . .SH DESCRIPTION .rs .sp This convenience function finds, for a compiled pattern, the first and last entries for a given name in the table that translates capturing parenthesis names into numbers. When names are required to be unique (PCRE_DUPNAMES is \fInot\fP set), it is usually easier to use \fBpcre[16]_get_stringnumber()\fP instead. .sp \fIcode\fP Compiled regular expression \fIname\fP Name whose entries required \fIfirst\fP Where to return a pointer to the first entry \fIlast\fP Where to return a pointer to the last entry .sp The yield of the function is the length of each entry, or PCRE_ERROR_NOSUBSTRING if none are found. .P There is a complete description of the PCRE native API, including the format of the table entries, in the .\" HREF \fBpcreapi\fP .\" page, and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcreprecompile.30000644000222100022210000001361111735643377013167 00000000000000.TH PCREPRECOMPILE 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "SAVING AND RE-USING PRECOMPILED PCRE PATTERNS" .rs .sp If you are running an application that uses a large number of regular expression patterns, it may be useful to store them in a precompiled form instead of having to compile them every time the application is run. If you are not using any private character tables (see the .\" HREF \fBpcre_maketables()\fP .\" documentation), this is relatively straightforward. If you are using private tables, it is a little bit more complicated. However, if you are using the just-in-time optimization feature, it is not possible to save and reload the JIT data. .P If you save compiled patterns to a file, you can copy them to a different host and run them there. If the two hosts have different endianness (byte order), you should run the \fBpcre[16]_pattern_to_host_byte_order()\fP function on the new host before trying to match the pattern. The matching functions return PCRE_ERROR_BADENDIANNESS if they detect a pattern with the wrong endianness. .P Compiling regular expressions with one version of PCRE for use with a different version is not guaranteed to work and may cause crashes, and saving and restoring a compiled pattern loses any JIT optimization data. . . .SH "SAVING A COMPILED PATTERN" .rs .sp The value returned by \fBpcre[16]_compile()\fP points to a single block of memory that holds the compiled pattern and associated data. You can find the length of this block in bytes by calling \fBpcre[16]_fullinfo()\fP with an argument of PCRE_INFO_SIZE. You can then save the data in any appropriate manner. Here is sample code for the 8-bit library that compiles a pattern and writes it to a file. It assumes that the variable \fIfd\fP refers to a file that is open for output: .sp int erroroffset, rc, size; char *error; pcre *re; .sp re = pcre_compile("my pattern", 0, &error, &erroroffset, NULL); if (re == NULL) { ... handle errors ... } rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); if (rc < 0) { ... handle errors ... } rc = fwrite(re, 1, size, fd); if (rc != size) { ... handle errors ... } .sp In this example, the bytes that comprise the compiled pattern are copied exactly. Note that this is binary data that may contain any of the 256 possible byte values. On systems that make a distinction between binary and non-binary data, be sure that the file is opened for binary output. .P If you want to write more than one pattern to a file, you will have to devise a way of separating them. For binary data, preceding each pattern with its length is probably the most straightforward approach. Another possibility is to write out the data in hexadecimal instead of binary, one pattern to a line. .P Saving compiled patterns in a file is only one possible way of storing them for later use. They could equally well be saved in a database, or in the memory of some daemon process that passes them via sockets to the processes that want them. .P If the pattern has been studied, it is also possible to save the normal study data in a similar way to the compiled pattern itself. However, if the PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is created cannot be saved because it is too dependent on the current environment. When studying generates additional information, \fBpcre[16]_study()\fP returns a pointer to a \fBpcre[16]_extra\fP data block. Its format is defined in the .\" HTML .\" section on matching a pattern .\" in the .\" HREF \fBpcreapi\fP .\" documentation. The \fIstudy_data\fP field points to the binary study data, and this is what you must save (not the \fBpcre[16]_extra\fP block itself). The length of the study data can be obtained by calling \fBpcre[16]_fullinfo()\fP with an argument of PCRE_INFO_STUDYSIZE. Remember to check that \fBpcre[16]_study()\fP did return a non-NULL value before trying to save the study data. . . .SH "RE-USING A PRECOMPILED PATTERN" .rs .sp Re-using a precompiled pattern is straightforward. Having reloaded it into main memory, called \fBpcre[16]_pattern_to_host_byte_order()\fP if necessary, you pass its pointer to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP in the usual way. .P However, if you passed a pointer to custom character tables when the pattern was compiled (the \fItableptr\fP argument of \fBpcre[16]_compile()\fP), you must now pass a similar pointer to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP, because the value saved with the compiled pattern will obviously be nonsense. A field in a \fBpcre[16]_extra()\fP block is used to pass this data, as described in the .\" HTML .\" section on matching a pattern .\" in the .\" HREF \fBpcreapi\fP .\" documentation. .P If you did not provide custom character tables when the pattern was compiled, the pointer in the compiled pattern is NULL, which causes the matching functions to use PCRE's internal tables. Thus, you do not need to take any special action at run time in this case. .P If you saved study data with the compiled pattern, you need to create your own \fBpcre[16]_extra\fP data block and set the \fIstudy_data\fP field to point to the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA bit in the \fIflags\fP field to indicate that study data is present. Then pass the \fBpcre[16]_extra\fP block to the matching function in the usual way. If the pattern was studied for just-in-time optimization, that data cannot be saved, and so is lost by a save/restore cycle. . . .SH "COMPATIBILITY WITH DIFFERENT PCRE RELEASES" .rs .sp In general, it is safest to recompile all saved patterns when you update to a new PCRE release, though not all updates actually require this. . . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcrepartial.30000644000222100022210000004641711762370425012465 00000000000000.TH PCREPARTIAL 3 "24 February 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions .SH "PARTIAL MATCHING IN PCRE" .rs .sp In normal use of PCRE, if the subject string that is passed to a matching function matches as far as it goes, but is too short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances where it might be helpful to distinguish this case from other cases in which there is no match. .P Consider, for example, an application where a human is required to type in data for a field with specific formatting requirements. An example might be a date in the form \fIddmmmyy\fP, defined by this pattern: .sp ^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$ .sp If the application sees the user's keystrokes one by one, and can check that what has been typed so far is potentially valid, it is able to raise an error as soon as a mistake is made, by beeping and not reflecting the character that has been typed, for example. This immediate feedback is likely to be a better user interface than a check that is delayed until the entire string has been entered. Partial matching can also be useful when the subject string is very long and is not all available at once. .P PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and PCRE_PARTIAL_HARD options, which can be set when calling any of the matching functions. For backwards compatibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. The essential difference between the two options is whether or not a partial match is preferred to an alternative complete match, though the details differ between the two types of matching function. If both options are set, PCRE_PARTIAL_HARD takes precedence. .P If you want to use partial matching with just-in-time optimized code, you must call \fBpcre_study()\fP or \fBpcre16_study()\fP with one or both of these options: .sp PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE .sp PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non-partial matches on the same pattern. If the appropriate JIT study mode has not been set for a match, the interpretive matching code is used. .P Setting a partial matching option disables two of PCRE's standard optimizations. PCRE remembers the last literal data unit in a pattern, and abandons matching immediately if it is not present in the subject string. This optimization cannot be used for a subject string that might match only partially. If the pattern was studied, PCRE knows the minimum length of a matching string, and does not bother to run the matching function on shorter strings. This optimization is also disabled for partial matching. . . .SH "PARTIAL MATCHING USING pcre_exec() OR pcre16_exec()" .rs .sp A partial match occurs during a call to \fBpcre_exec()\fP or \fBpcre16_exec()\fP when the end of the subject string is reached successfully, but matching cannot continue because more characters are needed. However, at least one character in the subject must have been inspected. This character need not form part of the final matched string; lookbehind assertions and the \eK escape sequence provide ways of inspecting characters before the start of a matched substring. The requirement for inspecting at least one character exists because an empty string can always be matched; without such a restriction there would always be a partial match of an empty string at the end of the subject. .P If there are at least two slots in the offsets vector when a partial match is returned, the first slot is set to the offset of the earliest character that was inspected. For convenience, the second offset points to the end of the subject so that a substring can easily be identified. .P For the majority of patterns, the first offset identifies the start of the partially matched string. However, for patterns that contain lookbehind assertions, or \eK, or begin with \eb or \eB, earlier characters have been inspected while carrying out the match. For example: .sp /(?<=abc)123/ .sp This pattern matches "123", but only if it is preceded by "abc". If the subject string is "xyzabc12", the offsets after a partial match are for the substring "abc12", because all these characters are needed if another match is tried with extra characters added to the subject. .P What happens when a partial match is identified depends on which of the two partial matching options are set. . . .SS "PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec()" .rs .sp If PCRE_PARTIAL_SOFT is set when \fBpcre_exec()\fP or \fBpcre16_exec()\fP identifies a partial match, the partial match is remembered, but matching continues as normal, and other alternatives in the pattern are tried. If no complete match can be found, PCRE_ERROR_PARTIAL is returned instead of PCRE_ERROR_NOMATCH. .P This option is "soft" because it prefers a complete match over a partial match. All the various matching items in a pattern behave as if the subject string is potentially complete. For example, \ez, \eZ, and $ match at the end of the subject, as normal, and for \eb and \eB the end of the subject is treated as a non-alphanumeric. .P If there is more than one partial match, the first one that was found provides the data that is returned. Consider this pattern: .sp /123\ew+X|dogY/ .sp If this is matched against the subject string "abc123dog", both alternatives fail to match, but the end of the subject is reached during matching, so PCRE_ERROR_PARTIAL is returned. The offsets are set to 3 and 9, identifying "123dog" as the first partial match that was found. (In this example, there are two partial matches, because "dog" on its own partially matches the second alternative.) . . .SS "PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec()" .rs .sp If PCRE_PARTIAL_HARD is set for \fBpcre_exec()\fP or \fBpcre16_exec()\fP, PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, without continuing to search for possible complete matches. This option is "hard" because it prefers an earlier partial match over a later complete match. For this reason, the assumption is made that the end of the supplied subject string may not be the true end of the available data, and so, if \ez, \eZ, \eb, \eB, or $ are encountered at the end of the subject, the result is PCRE_ERROR_PARTIAL, provided that at least one character in the subject has been inspected. .P Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 subject strings are checked for validity. Normally, an invalid sequence causes the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the special case of a truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when PCRE_PARTIAL_HARD is set. . . .SS "Comparing hard and soft partial matching" .rs .sp The difference between the two partial matching options can be illustrated by a pattern such as: .sp /dog(sbody)?/ .sp This matches either "dog" or "dogsbody", greedily (that is, it prefers the longer string if possible). If it is matched against the string "dog" with PCRE_PARTIAL_SOFT, it yields a complete match for "dog". However, if PCRE_PARTIAL_HARD is set, the result is PCRE_ERROR_PARTIAL. On the other hand, if the pattern is made ungreedy the result is different: .sp /dog(sbody)??/ .sp In this case the result is always a complete match because that is found first, and matching never continues after finding a complete match. It might be easier to follow this explanation by thinking of the two patterns like this: .sp /dog(sbody)?/ is the same as /dogsbody|dog/ /dog(sbody)??/ is the same as /dog|dogsbody/ .sp The second pattern will never match "dogsbody", because it will always find the shorter match first. . . .SH "PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec()" .rs .sp The DFA functions move along the subject string character by character, without backtracking, searching for all possible matches simultaneously. If the end of the subject is reached before the end of the pattern, there is the possibility of a partial match, again provided that at least one character has been inspected. .P When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there have been no complete matches. Otherwise, the complete matches are returned. However, if PCRE_PARTIAL_HARD is set, a partial match takes precedence over any complete matches. The portion of the string that was inspected when the longest partial match was found is set as the first matching string, provided there are at least two slots in the offsets vector. .P Because the DFA functions always search for all possible matches, and there is no difference between greedy and ungreedy repetition, their behaviour is different from the standard functions when PCRE_PARTIAL_HARD is set. Consider the string "dog" matched against the ungreedy pattern shown above: .sp /dog(sbody)??/ .sp Whereas the standard functions stop as soon as they find the complete match for "dog", the DFA functions also find the partial match for "dogsbody", and so return that when PCRE_PARTIAL_HARD is set. . . .SH "PARTIAL MATCHING AND WORD BOUNDARIES" .rs .sp If a pattern ends with one of sequences \eb or \eB, which test for word boundaries, partial matching with PCRE_PARTIAL_SOFT can give counter-intuitive results. Consider this pattern: .sp /\ebcat\eb/ .sp This matches "cat", provided there is a word boundary at either end. If the subject string is "the cat", the comparison of the final "t" with a following character cannot take place, so a partial match is found. However, normal matching carries on, and \eb matches at the end of the subject when the last character is a letter, so a complete match is found. The result, therefore, is \fInot\fP PCRE_ERROR_PARTIAL. Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because then the partial match takes precedence. . . .SH "FORMERLY RESTRICTED PATTERNS" .rs .sp For releases of PCRE prior to 8.00, because of the way certain internal optimizations were implemented in the \fBpcre_exec()\fP function, the PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be used with all patterns. From release 8.00 onwards, the restrictions no longer apply, and partial matching with can be requested for any pattern. .P Items that were formerly restricted were repeated single characters and repeated metasequences. If PCRE_PARTIAL was set for a pattern that did not conform to the restrictions, \fBpcre_exec()\fP returned the error code PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The PCRE_INFO_OKPARTIAL call to \fBpcre_fullinfo()\fP to find out if a compiled pattern can be used for partial matching now always returns 1. . . .SH "EXAMPLE OF PARTIAL MATCHING USING PCRETEST" .rs .sp If the escape sequence \eP is present in a \fBpcretest\fP data line, the PCRE_PARTIAL_SOFT option is used for the match. Here is a run of \fBpcretest\fP that uses the date example quoted above: .sp re> /^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$/ data> 25jun04\eP 0: 25jun04 1: jun data> 25dec3\eP Partial match: 23dec3 data> 3ju\eP Partial match: 3ju data> 3juj\eP No match data> j\eP No match .sp The first data string is matched completely, so \fBpcretest\fP shows the matched substrings. The remaining four strings do not match the complete pattern, but the first two are partial matches. Similar output is obtained if DFA matching is used. .P If the escape sequence \eP is present more than once in a \fBpcretest\fP data line, the PCRE_PARTIAL_HARD option is set for the match. . . .SH "MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec()" .rs .sp When a partial match has been found using a DFA matching function, it is possible to continue the match by providing additional subject data and calling the function again with the same compiled regular expression, this time setting the PCRE_DFA_RESTART option. You must pass the same working space as before, because this is where details of the previous partial match are stored. Here is an example using \fBpcretest\fP, using the \eR escape sequence to set the PCRE_DFA_RESTART option (\eD specifies the use of the DFA matching function): .sp re> /^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$/ data> 23ja\eP\eD Partial match: 23ja data> n05\eR\eD 0: n05 .sp The first call has "23ja" as the subject, and requests partial matching; the second call has "n05" as the subject for the continued (restarted) match. Notice that when the match is complete, only the last part is shown; PCRE does not retain the previously partially-matched string. It is up to the calling program to do that if it needs to. .P You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with PCRE_DFA_RESTART to continue partial matching over multiple segments. This facility can be used to pass very long subject strings to the DFA matching functions. . . .SH "MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec()" .rs .sp From release 8.00, the standard matching functions can also be used to do multi-segment matching. Unlike the DFA functions, it is not possible to restart the previous match with a new segment of data. Instead, new data must be added to the previous subject string, and the entire match re-run, starting from the point where the partial match occurred. Earlier data can be discarded. .P It is best to use PCRE_PARTIAL_HARD in this situation, because it does not treat the end of a segment as the end of the subject when matching \ez, \eZ, \eb, \eB, and $. Consider an unanchored pattern that matches dates: .sp re> /\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed/ data> The date is 23ja\eP\eP Partial match: 23ja .sp At this stage, an application could discard the text preceding "23ja", add on text from the next segment, and call the matching function again. Unlike the DFA matching functions, the entire matching string must always be available, and the complete matching process occurs for each call, so more memory and more processing time is needed. .P \fBNote:\fP If the pattern contains lookbehind assertions, or \eK, or starts with \eb or \eB, the string that is returned for a partial match includes characters that precede the partially matched string itself, because these must be retained when adding on more characters for a subsequent matching attempt. However, in some cases you may need to retain even earlier characters, as discussed in the next section. . . .SH "ISSUES WITH MULTI-SEGMENT MATCHING" .rs .sp Certain types of pattern may give problems with multi-segment matching, whichever matching function is used. .P 1. If the pattern contains a test for the beginning of a line, you need to pass the PCRE_NOTBOL option when the subject string for any call does start at the beginning of a line. There is also a PCRE_NOTEOL option, but in practice when doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL. .P 2. Lookbehind assertions that have already been obeyed are catered for in the offsets that are returned for a partial match. However a lookbehind assertion later in the pattern could require even earlier characters to be inspected. You can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the \fBpcre_fullinfo()\fP or \fBpcre16_fullinfo()\fP functions to obtain the length of the largest lookbehind in the pattern. This length is given in characters, not bytes. If you always retain at least that many characters before the partially matched string, all should be well. (Of course, near the start of the subject, fewer characters may be present; in that case all characters should be retained.) .P 3. Because a partial match must always contain at least one character, what might be considered a partial match of an empty string actually gives a "no match" result. For example: .sp re> /c(?<=abc)x/ data> ab\eP No match .sp If the next segment begins "cx", a match should be found, but this will only happen if characters from the previous segment are retained. For this reason, a "no match" result should be interpreted as "partial match of an empty string" when the pattern contains lookbehinds. .P 4. Matching a subject string that is split into multiple segments may not always produce exactly the same result as matching over one single long string, especially when PCRE_PARTIAL_SOFT is used. The section "Partial Matching and Word Boundaries" above describes an issue that arises if the pattern ends with \eb or \eB. Another kind of difference may occur when there are multiple matching possibilities, because (for PCRE_PARTIAL_SOFT) a partial match result is given only when there are no completed matches. This means that as soon as the shortest match has been found, continuation to a new subject segment is no longer possible. Consider again this \fBpcretest\fP example: .sp re> /dog(sbody)?/ data> dogsb\eP 0: dog data> do\eP\eD Partial match: do data> gsb\eR\eP\eD 0: g data> dogsbody\eD 0: dogsbody 1: dog .sp The first data line passes the string "dogsb" to a standard matching function, setting the PCRE_PARTIAL_SOFT option. Although the string is a partial match for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter string "dog" is a complete match. Similarly, when the subject is presented to a DFA matching function in several parts ("do" and "gsb" being the first two) the match stops when "dog" has been found, and it is not possible to continue. On the other hand, if "dogsbody" is presented as a single string, a DFA matching function finds both matches. .P Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching multi-segment data. The example above then behaves differently: .sp re> /dog(sbody)?/ data> dogsb\eP\eP Partial match: dogsb data> do\eP\eD Partial match: do data> gsb\eR\eP\eP\eD Partial match: gsb .sp 5. Patterns that contain alternatives at the top level which do not all start with the same pattern item may not work as expected when PCRE_DFA_RESTART is used. For example, consider this pattern: .sp 1234|3789 .sp If the first part of the subject is "ABC123", a partial match of the first alternative is found at offset 3. There is no partial match for the second alternative, because such a match does not start at the same point in the subject string. Attempting to continue with the string "7890" does not yield a match because only those alternatives that match at one point in the subject are remembered. The problem arises because the start of the second alternative matches within the first alternative. There is no problem with anchored patterns or patterns such as: .sp 1234|ABCD .sp where no string can be a partial match for both alternatives. This is not a problem if a standard matching function is used, because the entire match has to be rerun each time: .sp re> /1234|3789/ data> ABC123\eP\eP Partial match: 123 data> 1237890 0: 3789 .sp Of course, instead of using PCRE_DFA_RESTART, the same technique of re-running the entire match can also be used with the DFA matching functions. Another possibility is to work with two buffers. If a partial match at offset \fIn\fP in the first buffer is followed by "no match" when PCRE_DFA_RESTART is used on the second buffer, you can then try a new match starting at offset \fIn+1\fP in the first buffer. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 24 February 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre_assign_jit_stack.30000644000222100022210000000340711760163326014475 00000000000000.TH PCRE_ASSIGN_JIT_STACK 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP, .ti +5n .B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP); .PP .B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP, .ti +5n .B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP); . .SH DESCRIPTION .rs .sp This function provides control over the memory used as a stack at run-time by a call to \fBpcre[16]_exec()\fP with a pattern that has been successfully compiled with JIT optimization. The arguments are: .sp extra the data pointer returned by \fBpcre[16]_study()\fP callback a callback function data a JIT stack or a value to be passed to the callback function .P If \fIcallback\fP is NULL and \fIdata\fP is NULL, an internal 32K block on the machine stack is used. .P If \fIcallback\fP is NULL and \fIdata\fP is not NULL, \fIdata\fP must be a valid JIT stack, the result of calling \fBpcre[16]_jit_stack_alloc()\fP. .P If \fIcallback\fP not NULL, it is called with \fIdata\fP as an argument at the start of matching, in order to set up a JIT stack. If the result is NULL, the internal 32K stack is used; otherwise the return value must be a valid JIT stack, the result of calling \fBpcre[16]_jit_stack_alloc()\fP. .P You may safely assign the same JIT stack to multiple patterns, as long as they are all matched in the same thread. In a multithread application, each thread must use its own JIT stack. For more details, see the .\" HREF \fBpcrejit\fP .\" page. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_copy_named_substring.30000644000222100022210000000276611735631166015407 00000000000000.TH PCRE_COPY_NAMED_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_copy_named_substring(const pcre *\fIcode\fP, .ti +5n .B const char *\fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B char *\fIbuffer\fP, int \fIbuffersize\fP); .PP .B int pcre16_copy_named_substring(const pcre16 *\fIcode\fP, .ti +5n .B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, .ti +5n .B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, .ti +5n .B PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for extracting a captured substring, identified by name, into a given buffer. The arguments are: .sp \fIcode\fP Pattern that was successfully matched \fIsubject\fP Subject that has been successfully matched \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringname\fP Name of the required substring \fIbuffer\fP Buffer to receive the string \fIbuffersize\fP Size of buffer .sp The yield is the length of the substring, PCRE_ERROR_NOMEMORY if the buffer was too small, or PCRE_ERROR_NOSUBSTRING if the string name is invalid. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcre_fullinfo.30000644000222100022210000000574311735631357013007 00000000000000.TH PCRE_FULLINFO 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_fullinfo(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B int \fIwhat\fP, void *\fIwhere\fP); .PP .B int pcre16_fullinfo(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," .ti +5n .B int \fIwhat\fP, void *\fIwhere\fP); . .SH DESCRIPTION .rs .sp This function returns information about a compiled pattern. Its arguments are: .sp \fIcode\fP Compiled regular expression \fIextra\fP Result of \fBpcre[16]_study()\fP or NULL \fIwhat\fP What information is required \fIwhere\fP Where to put the information .sp The following information is available: .sp PCRE_INFO_BACKREFMAX Number of highest back reference PCRE_INFO_CAPTURECOUNT Number of capturing subpatterns PCRE_INFO_DEFAULT_TABLES Pointer to default tables PCRE_INFO_FIRSTBYTE Fixed first data unit for a match, or -1 for start of string or after newline, or -2 otherwise PCRE_INFO_FIRSTTABLE Table of first data units (after studying) PCRE_INFO_HASCRORLF Return 1 if explicit CR or LF matches exist PCRE_INFO_JCHANGED Return 1 if (?J) or (?-J) was used PCRE_INFO_JIT Return 1 after successful JIT compilation PCRE_INFO_JITSIZE Size of JIT compiled code PCRE_INFO_LASTLITERAL Literal last data unit required PCRE_INFO_MINLENGTH Lower bound length of matching strings PCRE_INFO_NAMECOUNT Number of named subpatterns PCRE_INFO_NAMEENTRYSIZE Size of name table entry PCRE_INFO_NAMETABLE Pointer to name table PCRE_INFO_OKPARTIAL Return 1 if partial matching can be tried (always returns 1 after release 8.00) PCRE_INFO_OPTIONS Option bits used for compilation PCRE_INFO_SIZE Size of compiled pattern PCRE_INFO_STUDYSIZE Size of study data .sp The \fIwhere\fP argument must point to an integer variable, except for the following \fIwhat\fP values: .sp PCRE_INFO_DEFAULT_TABLES const unsigned char * PCRE_INFO_FIRSTTABLE const unsigned char * PCRE_INFO_NAMETABLE PCRE_SPTR16 (16-bit library) PCRE_INFO_NAMETABLE const unsigned char * (8-bit library) PCRE_INFO_OPTIONS unsigned long int PCRE_INFO_SIZE size_t .sp The yield of the function is zero on success or: .sp PCRE_ERROR_NULL the argument \fIcode\fP was NULL the argument \fIwhere\fP was NULL PCRE_ERROR_BADMAGIC the "magic number" was not found PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/doc/pcreunicode.30000644000222100022210000002311311760163326012441 00000000000000.TH PCREUNICODE 3 "14 April 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT" .rs .sp From Release 8.30, in addition to its previous UTF-8 support, PCRE also supports UTF-16 by means of a separate 16-bit library. This can be built as well as, or instead of, the 8-bit library. . . .SH "UTF-8 SUPPORT" .rs .sp In order process UTF-8 strings, you must build PCRE's 8-bit library with UTF support, and, in addition, you must call .\" HREF \fBpcre_compile()\fP .\" with the PCRE_UTF8 option flag, or the pattern must start with the sequence (*UTF8). When either of these is the case, both the pattern and any subject strings that are matched against it are treated as UTF-8 strings instead of strings of 1-byte characters. . . .SH "UTF-16 SUPPORT" .rs .sp In order process UTF-16 strings, you must build PCRE's 16-bit library with UTF support, and, in addition, you must call .\" HTML .\" \fBpcre16_compile()\fP .\" with the PCRE_UTF16 option flag, or the pattern must start with the sequence (*UTF16). When either of these is the case, both the pattern and any subject strings that are matched against it are treated as UTF-16 strings instead of strings of 16-bit characters. . . .SH "UTF SUPPORT OVERHEAD" .rs .sp If you compile PCRE with UTF support, but do not use it at run time, the library will be a bit bigger, but the additional run time overhead is limited to testing the PCRE_UTF8/16 flag occasionally, so should not be very big. . . .SH "UNICODE PROPERTY SUPPORT" .rs .sp If PCRE is built with Unicode character property support (which implies UTF support), the escape sequences \ep{..}, \eP{..}, and \eX can be used. The available properties that can be tested are limited to the general category properties such as Lu for an upper case letter or Nd for a decimal number, the Unicode script names such as Arabic or Han, and the derived properties Any and L&. A full list is given in the .\" HREF \fBpcrepattern\fP .\" documentation. Only the short names for properties are supported. For example, \ep{L} matches a letter. Its Perl synonym, \ep{Letter}, is not supported. Furthermore, in Perl, many properties may optionally be prefixed by "Is", for compatibility with Perl 5.6. PCRE does not support this. . . .\" HTML .SS "Validity of UTF-8 strings" .rs .sp When you set the PCRE_UTF8 flag, the byte strings passed as patterns and subjects are (by default) checked for validity on entry to the relevant functions. The entire string is checked before any other processing takes place. From release 7.3 of PCRE, the check is according the rules of RFC 3629, which are themselves derived from the Unicode specification. Earlier releases of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0 to U+10FFFF, excluding U+D800 to U+DFFF. .P The excluded code points are the "Surrogate Area" of Unicode. They are reserved for use by UTF-16, where they are used in pairs to encode codepoints with values greater than 0xFFFF. The code points that are encoded by UTF-16 pairs are available independently in the UTF-8 encoding. (In other words, the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8.) .P If an invalid UTF-8 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first byte of the failing character. The run-time functions \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP also pass back this information, as well as a more detailed reason code if the caller has provided memory in which to do this. .P In some situations, you may already know that your strings are valid, and therefore want to skip these checks in order to improve performance, for example in the case of a long subject string that is being scanned repeatedly with different patterns. If you set the PCRE_NO_UTF8_CHECK flag at compile time or at run time, PCRE assumes that the pattern or subject it is given (respectively) contains only valid UTF-8 codes. In this case, it does not diagnose an invalid UTF-8 string. .P If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what happens depends on why the string is invalid. If the string conforms to the "old" definition of UTF-8 (RFC 2279), it is processed as a string of characters in the range 0 to 0x7FFFFFFF by \fBpcre_dfa_exec()\fP and the interpreted version of \fBpcre_exec()\fP. In other words, apart from the initial validity test, these functions (when in UTF-8 mode) handle strings according to the more liberal rules of RFC 2279. However, the just-in-time (JIT) optimization for \fBpcre_exec()\fP supports only RFC 3629. If you are using JIT optimization, or if the string does not even conform to RFC 2279, the result is undefined. Your program may crash. .P If you want to process strings of values in the full range 0 to 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this situation, you will have to apply your own validity check, and avoid the use of JIT optimization. . . .\" HTML .SS "Validity of UTF-16 strings" .rs .sp When you set the PCRE_UTF16 flag, the strings of 16-bit data units that are passed as patterns and subjects are (by default) checked for validity on entry to the relevant functions. Values other than those in the surrogate range U+D800 to U+DFFF are independent code points. Values in the surrogate range must be used in pairs in the correct manner. .P If an invalid UTF-16 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first data unit of the failing character. The run-time functions \fBpcre16_exec()\fP and \fBpcre16_dfa_exec()\fP also pass back this information, as well as a more detailed reason code if the caller has provided memory in which to do this. .P In some situations, you may already know that your strings are valid, and therefore want to skip these checks in order to improve performance. If you set the PCRE_NO_UTF16_CHECK flag at compile time or at run time, PCRE assumes that the pattern or subject it is given (respectively) contains only valid UTF-16 sequences. In this case, it does not diagnose an invalid UTF-16 string. . . .SS "General comments about UTF modes" .rs .sp 1. Codepoints less than 256 can be specified by either braced or unbraced hexadecimal escape sequences (for example, \ex{b3} or \exb3). Larger values have to use braced sequences. .P 2. Octal numbers up to \e777 are recognized, and in UTF-8 mode, they match two-byte characters for values greater than \e177. .P 3. Repeat quantifiers apply to complete UTF characters, not to individual data units, for example: \ex{100}{3}. .P 4. The dot metacharacter matches one UTF character instead of a single data unit. .P 5. The escape sequence \eC can be used to match a single byte in UTF-8 mode, or a single 16-bit data unit in UTF-16 mode, but its use can lead to some strange effects because it breaks up multi-unit characters (see the description of \eC in the .\" HREF \fBpcrepattern\fP .\" documentation). The use of \eC is not supported in the alternative matching function \fBpcre[16]_dfa_exec()\fP, nor is it supported in UTF mode by the JIT optimization of \fBpcre[16]_exec()\fP. If JIT optimization is requested for a UTF pattern that contains \eC, it will not succeed, and so the matching will be carried out by the normal interpretive function. .P 6. The character escapes \eb, \eB, \ed, \eD, \es, \eS, \ew, and \eW correctly test characters of any code value, but, by default, the characters that PCRE recognizes as digits, spaces, or word characters remain the same set as in non-UTF mode, all with values less than 256. This remains true even when PCRE is built to include Unicode property support, because to do otherwise would slow down PCRE in many common cases. Note in particular that this applies to \eb and \eB, because they are defined in terms of \ew and \eW. If you really want to test for a wider sense of, say, "digit", you can use explicit Unicode property tests such as \ep{Nd}. Alternatively, if you set the PCRE_UCP option, the way that the character escapes work is changed so that Unicode properties are used to determine which characters match. There are more details in the section on .\" HTML .\" generic character types .\" in the .\" HREF \fBpcrepattern\fP .\" documentation. .P 7. Similarly, characters that match the POSIX named character classes are all low-valued characters, unless the PCRE_UCP option is set. .P 8. However, the horizontal and vertical white space matching escapes (\eh, \eH, \ev, and \eV) do match all the appropriate Unicode characters, whether or not PCRE_UCP is set. .P 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. Furthermore, 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 supported by PCRE. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 14 April 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcresample.30000644000222100022210000000621711735643421012303 00000000000000.TH PCRESAMPLE 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE SAMPLE PROGRAM" .rs .sp A simple, complete demonstration program, to get you started with using PCRE, is supplied in the file \fIpcredemo.c\fP in the PCRE distribution. A listing of this program is given in the .\" HREF \fBpcredemo\fP .\" documentation. If you do not have a copy of the PCRE distribution, you can save this listing to re-create \fIpcredemo.c\fP. .P The demonstration program, which uses the original PCRE 8-bit library, compiles the regular expression that is its first argument, and matches it against the subject string in its second argument. No PCRE options are set, and default character tables are used. If matching succeeds, the program outputs the portion of the subject that matched, together with the contents of any captured substrings. .P If the -g option is given on the command line, the program then goes on to check for further matches of the same regular expression in the same subject string. The logic is a little bit tricky because of the possibility of matching an empty string. Comments in the code explain what is going on. .P If PCRE is installed in the standard include and library directories for your operating system, you should be able to compile the demonstration program using this command: .sp gcc -o pcredemo pcredemo.c -lpcre .sp If PCRE is installed elsewhere, you may need to add additional options to the command line. For example, on a Unix-like system that has PCRE installed in \fI/usr/local\fP, you can compile the demonstration program using a command like this: .sp .\" JOINSH gcc -o pcredemo -I/usr/local/include pcredemo.c \e -L/usr/local/lib -lpcre .sp In a Windows environment, if you want to statically link the program against a non-dll \fBpcre.a\fP file, you must uncomment the line that defines PCRE_STATIC before including \fBpcre.h\fP, because otherwise the \fBpcre_malloc()\fP and \fBpcre_free()\fP exported functions will be declared \fB__declspec(dllimport)\fP, with unwanted results. .P Once you have compiled and linked the demonstration program, you can run simple tests like this: .sp ./pcredemo 'cat|dog' 'the cat sat on the mat' ./pcredemo -g 'cat|dog' 'the dog sat on the cat' .sp Note that there is a much more comprehensive test program, called .\" HREF \fBpcretest\fP, .\" which supports many more facilities for testing regular expressions and both PCRE libraries. The .\" HREF \fBpcredemo\fP .\" program is provided as a simple coding example. .P If you try to run .\" HREF \fBpcredemo\fP .\" when PCRE is not installed in the standard library directory, you may get an error like this on some operating systems (e.g. Solaris): .sp ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or directory .sp This is caused by the way shared library support works on those systems. You need to add .sp -R/usr/local/lib .sp (for example) to the compile command to get round this problem. . . .SH AUTHOR .rs .sp .nf Philip Hazel University Computing Service Cambridge CB2 3QH, England. .fi . . .SH REVISION .rs .sp .nf Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. .fi pcre-8.31/doc/pcre-config.10000644000222100022210000000500011735626474012340 00000000000000.TH PCRE-CONFIG 1 "01 January 2012" "PCRE 8.30" .SH NAME pcre-config - program to return PCRE configuration .SH SYNOPSIS .rs .sp .B pcre-config [--prefix] [--exec-prefix] [--version] [--libs] .ti +5n .B [--libs16] [--libs-cpp] [--libs-posix] [--cflags] .ti +5n .B [--cflags-posix] . . .SH DESCRIPTION .rs .sp \fBpcre-config\fP returns the configuration of the installed PCRE libraries and the options required to compile a program to use them. Some of the options apply only to the 8-bit or 16-bit libraries, respectively, and are not available if only one of those libraries has been built. If an unavailable option is encountered, the "usage" information is output. . . .SH OPTIONS .rs .TP 10 \fB--prefix\fP Writes the directory prefix used in the PCRE installation for architecture independent files (\fI/usr\fP on many systems, \fI/usr/local\fP on some systems) to the standard output. .TP 10 \fB--exec-prefix\fP Writes the directory prefix used in the PCRE installation for architecture dependent files (normally the same as \fB--prefix\fP) to the standard output. .TP 10 \fB--version\fP Writes the version number of the installed PCRE libraries to the standard output. .TP 10 \fB--libs\fP Writes to the standard output the command line options required to link with the 8-bit PCRE library (\fB-lpcre\fP on many systems). .TP 10 \fB--libs16\fP Writes to the standard output the command line options required to link with the 16-bit PCRE library (\fB-lpcre16\fP on many systems). .TP 10 \fB--libs-cpp\fP Writes to the standard output the command line options required to link with PCRE's C++ wrapper library (\fB-lpcrecpp\fP \fB-lpcre\fP on many systems). .TP 10 \fB--libs-posix\fP Writes to the standard output the command line options required to link with PCRE's POSIX API wrapper library (\fB-lpcreposix\fP \fB-lpcre\fP on many systems). .TP 10 \fB--cflags\fP Writes to the standard output the command line options required to compile files that use PCRE (this may include some \fB-I\fP options, but is blank on many systems). .TP 10 \fB--cflags-posix\fP Writes to the standard output the command line options required to compile files that use PCRE's POSIX API wrapper library (this may include some \fB-I\fP options, but is blank on many systems). . . .SH "SEE ALSO" .rs .sp \fBpcre(3)\fP . . .SH AUTHOR .rs .sp This manual page was originally written by Mark Baker for the Debian GNU/Linux system. It has been subsequently revised as a generic PCRE man page. . . .SH REVISION .rs .sp .nf Last updated: 01 January 2012 .fi pcre-8.31/doc/pcre_refcount.30000644000222100022210000000151311735631632013001 00000000000000.TH PCRE_REFCOUNT 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS .rs .sp .B #include .PP .SM .B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); .PP .B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP); . .SH DESCRIPTION .rs .sp This function is used to maintain a reference count inside a data block that contains a compiled pattern. Its arguments are: .sp \fIcode\fP Compiled regular expression \fIadjust\fP Adjustment to reference value .sp The yield of the function is the adjusted reference value, which is constrained to lie between 0 and 65535. .P There is a complete description of the PCRE native API in the .\" HREF \fBpcreapi\fP .\" page and a description of the POSIX API in the .\" HREF \fBpcreposix\fP .\" page. pcre-8.31/NEWS0000644000222100022210000005403711775525217010027 00000000000000News about PCRE releases ------------------------ Release 8.31 06-July-2012 ------------------------- This is mainly a bug-fixing release, with a small number of developments: . The JIT compiler now supports partial matching and the (*MARK) and (*COMMIT) verbs. . PCRE_INFO_MAXLOOKBEHIND can be used to find the longest lookbehing in a pattern. . There should be a performance improvement when using the heap instead of the stack for recursion. . pcregrep can now be linked with libedit as an alternative to libreadline. . pcregrep now has a --file-list option where the list of files to scan is given as a file. . pcregrep now recognizes binary files and there are related options. . The Unicode tables have been updated to 6.1.0. As always, the full list of changes is in the ChangeLog file. Release 8.30 04-February-2012 ----------------------------- Release 8.30 introduces a major new feature: support for 16-bit character strings, compiled as a separate library. There are a few changes to the 8-bit library, in addition to some bug fixes. . The pcre_info() function, which has been obsolete for over 10 years, has been removed. . When a compiled pattern was saved to a file and later reloaded on a host with different endianness, PCRE used automatically to swap the bytes in some of the data fields. With the advent of the 16-bit library, where more of this swapping is needed, it is no longer done automatically. Instead, the bad endianness is detected and a specific error is given. The user can then call a new function called pcre_pattern_to_host_byte_order() (or an equivalent 16-bit function) to do the swap. . In UTF-8 mode, the values 0xd800 to 0xdfff are not legal Unicode code points and are now faulted. (They are the so-called "surrogates" that are reserved for coding high values in UTF-16.) Release 8.21 12-Dec-2011 ------------------------ This is almost entirely a bug-fix release. The only new feature is the ability to obtain the size of the memory used by the JIT compiler. Release 8.20 21-Oct-2011 ------------------------ The main change in this release is the inclusion of Zoltan Herczeg's just-in-time compiler support, which can be accessed by building PCRE with --enable-jit. Large performance benefits can be had in many situations. 8.20 also fixes an unfortunate bug that was introduced in 8.13 as well as tidying up a number of infelicities and differences from Perl. Release 8.13 16-Aug-2011 ------------------------ This is mainly a bug-fix release. There has been a lot of internal refactoring. The Unicode tables have been updated. The only new feature in the library is the passing of *MARK information to callouts. Some additions have been made to pcretest to make testing easier and more comprehensive. There is a new option for pcregrep to adjust its internal buffer size. Release 8.12 15-Jan-2011 ------------------------ This release fixes some bugs in pcregrep, one of which caused the tests to fail on 64-bit big-endian systems. There are no changes to the code of the library. Release 8.11 10-Dec-2010 ------------------------ A number of bugs in the library and in pcregrep have been fixed. As always, see ChangeLog for details. The following are the non-bug-fix changes: . Added --match-limit and --recursion-limit to pcregrep. . Added an optional parentheses number to the -o and --only-matching options of pcregrep. . Changed the way PCRE_PARTIAL_HARD affects the matching of $, \z, \Z, \b, and \B. . Added PCRE_ERROR_SHORTUTF8 to make it possible to distinguish between a bad UTF-8 sequence and one that is incomplete when using PCRE_PARTIAL_HARD. . Recognize (*NO_START_OPT) at the start of a pattern to set the PCRE_NO_ START_OPTIMIZE option, which is now allowed at compile time Release 8.10 25-Jun-2010 ------------------------ There are two major additions: support for (*MARK) and friends, and the option PCRE_UCP, which changes the behaviour of \b, \d, \s, and \w (and their opposites) so that they make use of Unicode properties. There are also a number of lesser new features, and several bugs have been fixed. A new option, --line-buffered, has been added to pcregrep, for use when it is connected to pipes. Release 8.02 19-Mar-2010 ------------------------ Another bug-fix release. Release 8.01 19-Jan-2010 ------------------------ This is a bug-fix release. Several bugs in the code itself and some bugs and infelicities in the build system have been fixed. Release 8.00 19-Oct-09 ---------------------- Bugs have been fixed in the library and in pcregrep. There are also some enhancements. Restrictions on patterns used for partial matching have been removed, extra information is given for partial matches, the partial matching process has been improved, and an option to make a partial match override a full match is available. The "study" process has been enhanced by finding a lower bound matching length. Groups with duplicate numbers may now have duplicated names without the use of PCRE_DUPNAMES. However, they may not have different names. The documentation has been revised to reflect these changes. The version number has been expanded to 3 digits as it is clear that the rate of change is not slowing down. Release 7.9 11-Apr-09 --------------------- Mostly bugfixes and tidies with just a couple of minor functional additions. Release 7.8 05-Sep-08 --------------------- More bug fixes, plus a performance improvement in Unicode character property lookup. Release 7.7 07-May-08 --------------------- This is once again mainly a bug-fix release, but there are a couple of new features. Release 7.6 28-Jan-08 --------------------- The main reason for having this release so soon after 7.5 is because it fixes a potential buffer overflow problem in pcre_compile() when run in UTF-8 mode. In addition, the CMake configuration files have been brought up to date. Release 7.5 10-Jan-08 --------------------- This is mainly a bug-fix release. However the ability to link pcregrep with libz or libbz2 and the ability to link pcretest with libreadline have been added. Also the --line-offsets and --file-offsets options were added to pcregrep. Release 7.4 21-Sep-07 --------------------- The only change of specification is the addition of options to control whether \R matches any Unicode line ending (the default) or just CR, LF, and CRLF. Otherwise, the changes are bug fixes and a refactoring to reduce the number of relocations needed in a shared library. There have also been some documentation updates, in particular, some more information about using CMake to build PCRE has been added to the NON-UNIX-USE file. Release 7.3 28-Aug-07 --------------------- Most changes are bug fixes. Some that are not: 1. There is some support for Perl 5.10's experimental "backtracking control verbs" such as (*PRUNE). 2. UTF-8 checking is now as per RFC 3629 instead of RFC 2279; this is more restrictive in the strings it accepts. 3. Checking for potential integer overflow has been made more dynamic, and as a consequence there is no longer a hard limit on the size of a subpattern that has a limited repeat count. 4. When CRLF is a valid line-ending sequence, pcre_exec() and pcre_dfa_exec() no longer advance by two characters instead of one when an unanchored match fails at CRLF if there are explicit CR or LF matches within the pattern. This gets rid of some anomalous effects that previously occurred. 5. Some PCRE-specific settings for varying the newline options at the start of a pattern have been added. Release 7.2 19-Jun-07 --------------------- WARNING: saved patterns that were compiled by earlier versions of PCRE must be recompiled for use with 7.2 (necessitated by the addition of \K, \h, \H, \v, and \V). Correction to the notes for 7.1: the note about shared libraries for Windows is wrong. Previously, three libraries were built, but each could function independently. For example, the pcreposix library also included all the functions from the basic pcre library. The change is that the three libraries are no longer independent. They are like the Unix libraries. To use the pcreposix functions, for example, you need to link with both the pcreposix and the basic pcre library. Some more features from Perl 5.10 have been added: (?-n) and (?+n) relative references for recursion and subroutines. (?(-n) and (?(+n) relative references as conditions. \k{name} and \g{name} are synonyms for \k. \K to reset the start of the matched string; for example, (foo)\Kbar matches bar preceded by foo, but only sets bar as the matched string. (?| introduces a group where the capturing parentheses in each alternative start from the same number; for example, (?|(abc)|(xyz)) sets capturing parentheses number 1 in both cases. \h, \H, \v, \V match horizontal and vertical whitespace, respectively. Release 7.1 24-Apr-07 --------------------- There is only one new feature in this release: a linebreak setting of PCRE_NEWLINE_ANYCRLF. It is a cut-down version of PCRE_NEWLINE_ANY, which recognizes only CRLF, CR, and LF as linebreaks. A few bugs are fixed (see ChangeLog for details), but the major change is a complete re-implementation of the build system. This now has full Autotools support and so is now "standard" in some sense. It should help with compiling PCRE in a wide variety of environments. NOTE: when building shared libraries for Windows, three dlls are now built, called libpcre, libpcreposix, and libpcrecpp. Previously, everything was included in a single dll. Another important change is that the dftables auxiliary program is no longer compiled and run at "make" time by default. Instead, a default set of character tables (assuming ASCII coding) is used. If you want to use dftables to generate the character tables as previously, add --enable-rebuild-chartables to the "configure" command. You must do this if you are compiling PCRE to run on a system that uses EBCDIC code. There is a discussion about character tables in the README file. The default is not to use dftables so that that there is no problem when cross-compiling. Release 7.0 19-Dec-06 --------------------- This release has a new major number because there have been some internal upheavals to facilitate the addition of new optimizations and other facilities, and to make subsequent maintenance and extension easier. Compilation is likely to be a bit slower, but there should be no major effect on runtime performance. Previously compiled patterns are NOT upwards compatible with this release. If you have saved compiled patterns from a previous release, you will have to re-compile them. Important changes that are visible to users are: 1. The Unicode property tables have been updated to Unicode 5.0.0, which adds some more scripts. 2. The option PCRE_NEWLINE_ANY causes PCRE to recognize any Unicode newline sequence as a newline. 3. The \R escape matches a single Unicode newline sequence as a single unit. 4. New features that will appear in Perl 5.10 are now in PCRE. These include alternative Perl syntax for named parentheses, and Perl syntax for recursion. 5. The C++ wrapper interface has been extended by the addition of a QuoteMeta function and the ability to allow copy construction and assignment. For a complete list of changes, see the ChangeLog file. 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 --------------------- Important changes in this release: 1. A number of new features have been added to pcregrep. 2. The Unicode property tables have been updated to Unicode 4.1.0, and the supported properties have been extended with script names such as "Arabic", and the derived properties "Any" and "L&". This has necessitated a change to the interal format of compiled patterns. Any saved compiled patterns that use \p or \P must be recompiled. 3. The specification of recursion in patterns has been changed so that all recursive subpatterns are automatically treated as atomic groups. Thus, for example, (?R) is treated as if it were (?>(?R)). This is necessary because otherwise there are situations where recursion does not work. See the ChangeLog for a complete list of changes, which include a number of bug fixes and tidies. Release 6.0 07-Jun-05 --------------------- The release number has been increased to 6.0 because of the addition of several major new pieces of functionality. A new function, pcre_dfa_exec(), which implements pattern matching using a DFA algorithm, has been added. This has a number of advantages for certain cases, though it does run more slowly, and lacks the ability to capture substrings. On the other hand, it does find all matches, not just the first, and it works better for partial matching. The pcrematching man page discusses the differences. The pcretest program has been enhanced so that it can make use of the new pcre_dfa_exec() matching function and the extra features it provides. The distribution now includes a C++ wrapper library. This is built automatically if a C++ compiler is found. The pcrecpp man page discusses this interface. The code itself has been re-organized into many more files, one for each function, so it no longer requires everything to be linked in when static linkage is used. As a consequence, some internal functions have had to have their names exposed. These functions all have names starting with _pcre_. They are undocumented, and are not intended for use by outside callers. The pcregrep program has been enhanced with new functionality such as multiline-matching and options for output more matching context. See the ChangeLog for a complete list of changes to the library and the utility programs. Release 5.0 13-Sep-04 --------------------- The licence under which PCRE is released has been changed to the more conventional "BSD" licence. In the code, some bugs have been fixed, and there are also some major changes in this release (which is why I've increased the number to 5.0). Some changes are internal rearrangements, and some provide a number of new facilities. The new features are: 1. There's an "automatic callout" feature that inserts callouts before every item in the regex, and there's a new callout field that gives the position in the pattern - useful for debugging and tracing. 2. The extra_data structure can now be used to pass in a set of character tables at exec time. This is useful if compiled regex are saved and re-used at a later time when the tables may not be at the same address. If the default internal tables are used, the pointer saved with the compiled pattern is now set to NULL, which means that you don't need to do anything special unless you are using custom tables. 3. It is possible, with some restrictions on the content of the regex, to request "partial" matching. A special return code is given if all of the subject string matched part of the regex. This could be useful for testing an input field as it is being typed. 4. There is now some optional support for Unicode character properties, which means that the patterns items such as \p{Lu} and \X can now be used. Only the general category properties are supported. If PCRE is compiled with this support, an additional 90K data structure is include, which increases the size of the library dramatically. 5. There is support for saving compiled patterns and re-using them later. 6. There is support for running regular expressions that were compiled on a different host with the opposite endianness. 7. The pcretest program has been extended to accommodate the new features. The main internal rearrangement is that sequences of literal characters are no longer handled as strings. Instead, each character is handled on its own. This makes some UTF-8 handling easier, and makes the support of partial matching possible. Compiled patterns containing long literal strings will be larger as a result of this change; I hope that performance will not be much affected. Release 4.5 01-Dec-03 --------------------- Again mainly a bug-fix and tidying release, with only a couple of new features: 1. It's possible now to compile PCRE so that it does not use recursive function calls when matching. Instead it gets memory from the heap. This slows things down, but may be necessary on systems with limited stacks. 2. UTF-8 string checking has been tightened to reject overlong sequences and to check that a starting offset points to the start of a character. Failure of the latter returns a new error code: PCRE_ERROR_BADUTF8_OFFSET. 3. PCRE can now be compiled for systems that use EBCDIC code. Release 4.4 21-Aug-03 --------------------- This is mainly a bug-fix and tidying release. The only new feature is that PCRE checks UTF-8 strings for validity by default. There is an option to suppress this, just in case anybody wants that teeny extra bit of performance. Releases 4.1 - 4.3 ------------------ Sorry, I forgot about updating the NEWS file for these releases. Please take a look at ChangeLog. Release 4.0 17-Feb-03 --------------------- There have been a lot of changes for the 4.0 release, adding additional functionality and mending bugs. Below is a list of the highlights of the new functionality. For full details of these features, please consult the documentation. For a complete list of changes, see the ChangeLog file. 1. Support for Perl's \Q...\E escapes. 2. "Possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java package. They provide some syntactic sugar for simple cases of "atomic grouping". 3. Support for the \G assertion. It is true when the current matching position is at the start point of the match. 4. A new feature that provides some of the functionality that Perl provides with (?{...}). The facility is termed a "callout". The way it is done in PCRE is for the caller to provide an optional function, by setting pcre_callout to its entry point. To get the function called, the regex must include (?C) at appropriate points. 5. Support for recursive calls to individual subpatterns. This makes it really easy to get totally confused. 6. Support for named subpatterns. The Python syntax (?P...) is used to name a group. 7. Several extensions to UTF-8 support; it is now fairly complete. There is an option for pcregrep to make it operate in UTF-8 mode. 8. The single man page has been split into a number of separate man pages. These also give rise to individual HTML pages which are put in a separate directory. There is an index.html page that lists them all. Some hyperlinking between the pages has been installed. Release 3.5 15-Aug-01 --------------------- 1. The configuring system has been upgraded to use later versions of autoconf and libtool. By default it builds both a shared and a static library if the OS supports it. You can use --disable-shared or --disable-static on the configure command if you want only one of them. 2. The pcretest utility is now installed along with pcregrep because it is useful for users (to test regexs) and by doing this, it automatically gets relinked by libtool. The documentation has been turned into a man page, so there are now .1, .txt, and .html versions in /doc. 3. Upgrades to pcregrep: (i) Added long-form option names like gnu grep. (ii) Added --help to list all options with an explanatory phrase. (iii) Added -r, --recursive to recurse into sub-directories. (iv) Added -f, --file to read patterns from a file. 4. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure script, to force use of CR or LF instead of \n in the source. On non-Unix systems, the value can be set in config.h. 5. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an absolute limit. Changed the text of the error message to make this clear, and likewise updated the man page. 6. The limit of 99 on the number of capturing subpatterns has been removed. The new limit is 65535, which I hope will not be a "real" limit. Release 3.3 01-Aug-00 --------------------- There is some support for UTF-8 character strings. This is incomplete and experimental. The documentation describes what is and what is not implemented. Otherwise, this is just a bug-fixing release. Release 3.0 01-Feb-00 --------------------- 1. A "configure" script is now used to configure PCRE for Unix systems. It builds a Makefile, a config.h file, and the pcre-config script. 2. PCRE is built as a shared library by default. 3. There is support for POSIX classes such as [:alpha:]. 5. There is an experimental recursion feature. ---------------------------------------------------------------------------- IMPORTANT FOR THOSE UPGRADING FROM VERSIONS BEFORE 2.00 Please note that there has been a change in the API such that a larger ovector is required at matching time, to provide some additional workspace. The new man page has details. This change was necessary in order to support some of the new functionality in Perl 5.005. IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.00 Another (I hope this is the last!) change has been made to the API for the pcre_compile() function. An additional argument has been added to make it possible to pass over a pointer to character tables built in the current locale by pcre_maketables(). To use the default tables, this new arguement should be passed as NULL. IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05 Yet another (and again I hope this really is the last) change has been made to the API for the pcre_exec() function. An additional argument has been added to make it possible to start the match other than at the start of the subject string. This is important if there are lookbehinds. The new man page has the details, but you just want to convert existing programs, all you need to do is to stick in a new fifth argument to pcre_exec(), with a value of zero. For example, change pcre_exec(pattern, extra, subject, length, options, ovec, ovecsize) to pcre_exec(pattern, extra, subject, length, 0, options, ovec, ovecsize) **** pcre-8.31/pcre_maketables.c0000644000222100022210000001274011676645226012613 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_maketables(), which builds character tables for PCRE in the current locale. The file is compiled on its own as part of the PCRE library. However, it is also included in the compilation of dftables.c, in which case the macro DFTABLES is defined. */ #ifndef DFTABLES # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "pcre_internal.h" #endif /************************************************* * Create PCRE character tables * *************************************************/ /* This function builds a set of character tables for use by PCRE and returns a pointer to them. They are build using the ctype functions, and consequently their contents will depend upon the current locale setting. When compiled as part of the library, the store is obtained via PUBL(malloc)(), but when compiled inside dftables, use malloc(). Arguments: none Returns: pointer to the contiguous block of data */ #ifdef COMPILE_PCRE8 const unsigned char * pcre_maketables(void) #else const unsigned char * pcre16_maketables(void) #endif { unsigned char *yield, *p; int i; #ifndef DFTABLES yield = (unsigned char*)(PUBL(malloc))(tables_length); #else yield = (unsigned char*)malloc(tables_length); #endif if (yield == NULL) return NULL; p = yield; /* First comes the lower casing table */ for (i = 0; i < 256; i++) *p++ = tolower(i); /* Next the case-flipping table */ for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); /* Then the character class tables. Don't try to be clever and save effort on exclusive ones - in some locales things may be different. Note that the table for "space" includes everything "isspace" gives, including VT in the default locale. This makes it work for the POSIX class [:space:]. Note also that it is possible for a character to be alnum or alpha without being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must test for alnum specially. */ memset(p, 0, cbit_length); for (i = 0; i < 256; i++) { if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7); if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7); if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7); if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7); if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7); } p += cbit_length; /* Finally, the character type table. In this, we exclude VT from the white space chars, because Perl doesn't recognize it as such for \s and for comments within regexes. */ for (i = 0; i < 256; i++) { int x = 0; if (i != 0x0b && isspace(i)) x += ctype_space; if (isalpha(i)) x += ctype_letter; if (isdigit(i)) x += ctype_digit; if (isxdigit(i)) x += ctype_xdigit; if (isalnum(i) || i == '_') x += ctype_word; /* Note: strchr includes the terminating zero in the characters it considers. In this instance, that is ok because we want binary zero to be flagged as a 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; } return yield; } /* End of pcre_maketables.c */ pcre-8.31/pcreposix.c0000644000222100022210000003647211770363601011503 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module is a wrapper that provides a POSIX API to the underlying PCRE functions. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Ensure that the PCREPOSIX_EXP_xxx macros are set appropriately for compiling these functions. This must come before including pcreposix.h, where they are set for an application (using these functions) if they have not previously been set. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # define PCREPOSIX_EXP_DECL extern __declspec(dllexport) # define PCREPOSIX_EXP_DEFN __declspec(dllexport) #endif /* We include pcre.h before pcre_internal.h so that the PCRE library functions are declared as "import" for Windows by defining PCRE_EXP_DECL as "import". This is needed even though pcre_internal.h itself includes pcre.h, because it does so after it has set PCRE_EXP_DECL to "export" if it is not already set. */ #include "pcre.h" #include "pcre_internal.h" #include "pcreposix.h" /* Table to translate PCRE compile time error codes into POSIX error codes. */ static const int eint[] = { 0, /* no error */ REG_EESCAPE, /* \ at end of pattern */ REG_EESCAPE, /* \c at end of pattern */ REG_EESCAPE, /* unrecognized character follows \ */ REG_BADBR, /* numbers out of order in {} quantifier */ /* 5 */ REG_BADBR, /* number too big in {} quantifier */ REG_EBRACK, /* missing terminating ] for character class */ REG_ECTYPE, /* invalid escape sequence in character class */ REG_ERANGE, /* range out of order in character class */ REG_BADRPT, /* nothing to repeat */ /* 10 */ REG_BADRPT, /* operand of unlimited repeat could match the empty string */ REG_ASSERT, /* internal error: unexpected repeat */ REG_BADPAT, /* unrecognized character after (? */ REG_BADPAT, /* POSIX named classes are supported only within a class */ REG_EPAREN, /* missing ) */ /* 15 */ REG_ESUBREG, /* reference to non-existent subpattern */ REG_INVARG, /* erroffset passed as NULL */ REG_INVARG, /* unknown option bit(s) set */ REG_EPAREN, /* missing ) after comment */ REG_ESIZE, /* parentheses nested too deeply */ /* 20 */ REG_ESIZE, /* regular expression too large */ REG_ESPACE, /* failed to get memory */ REG_EPAREN, /* unmatched parentheses */ REG_ASSERT, /* internal error: code overflow */ REG_BADPAT, /* unrecognized character after (?< */ /* 25 */ REG_BADPAT, /* lookbehind assertion is not fixed length */ REG_BADPAT, /* malformed number or name after (?( */ REG_BADPAT, /* conditional group contains more than two branches */ REG_BADPAT, /* assertion expected after (?( */ REG_BADPAT, /* (?R or (?[+-]digits must be followed by ) */ /* 30 */ REG_ECTYPE, /* unknown POSIX class name */ REG_BADPAT, /* POSIX collating elements are not supported */ REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */ REG_BADPAT, /* spare error */ REG_BADPAT, /* character value in \x{...} sequence is too large */ /* 35 */ REG_BADPAT, /* invalid condition (?(0) */ REG_BADPAT, /* \C not allowed in lookbehind assertion */ REG_EESCAPE, /* PCRE does not support \L, \l, \N, \U, or \u */ REG_BADPAT, /* number after (?C is > 255 */ REG_BADPAT, /* closing ) for (?C expected */ /* 40 */ REG_BADPAT, /* recursive call could loop indefinitely */ REG_BADPAT, /* unrecognized character after (?P */ REG_BADPAT, /* syntax error in subpattern name (missing terminator) */ REG_BADPAT, /* two named subpatterns have the same name */ REG_BADPAT, /* invalid UTF-8 string */ /* 45 */ 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, /* subpattern name is too long (maximum 32 characters) */ REG_BADPAT, /* too many named subpatterns (maximum 10,000) */ /* 50 */ REG_BADPAT, /* repeated subpattern is too long */ REG_BADPAT, /* octal value is greater than \377 (not in UTF-8 mode) */ REG_BADPAT, /* internal error: overran compiling workspace */ REG_BADPAT, /* internal error: previously-checked referenced subpattern not found */ REG_BADPAT, /* DEFINE group contains more than one branch */ /* 55 */ REG_BADPAT, /* repeating a DEFINE group is not allowed */ REG_INVARG, /* inconsistent NEWLINE options */ REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */ REG_BADPAT, /* a numbered reference must not be zero */ REG_BADPAT, /* an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) */ /* 60 */ REG_BADPAT, /* (*VERB) not recognized */ REG_BADPAT, /* number is too big */ REG_BADPAT, /* subpattern name expected */ REG_BADPAT, /* digit expected after (?+ */ REG_BADPAT, /* ] is an invalid data character in JavaScript compatibility mode */ /* 65 */ REG_BADPAT, /* different names for subpatterns of the same number are not allowed */ REG_BADPAT, /* (*MARK) must have an argument */ REG_INVARG, /* this version of PCRE is not compiled with PCRE_UCP support */ REG_BADPAT, /* \c must be followed by an ASCII character */ REG_BADPAT, /* \k is not followed by a braced, angle-bracketed, or quoted name */ /* 70 */ REG_BADPAT, /* internal error: unknown opcode in find_fixedlength() */ REG_BADPAT, /* \N is not supported in a class */ REG_BADPAT, /* too many forward references */ REG_BADPAT, /* disallowed UTF-8/16 code point (>= 0xd800 && <= 0xdfff) */ REG_BADPAT, /* invalid UTF-16 string (should not occur) */ /* 75 */ REG_BADPAT, /* overlong MARK name */ REG_BADPAT /* character value in \u.... sequence is too large */ }; /* Table of texts corresponding to POSIX error codes */ static const char *const pstring[] = { "", /* Dummy for value 0 */ "internal error", /* REG_ASSERT */ "invalid repeat counts in {}", /* BADBR */ "pattern error", /* BADPAT */ "? * + invalid", /* BADRPT */ "unbalanced {}", /* EBRACE */ "unbalanced []", /* EBRACK */ "collation error - not relevant", /* ECOLLATE */ "bad class", /* ECTYPE */ "bad escape sequence", /* EESCAPE */ "empty expression", /* EMPTY */ "unbalanced ()", /* EPAREN */ "bad range inside []", /* ERANGE */ "expression too big", /* ESIZE */ "failed to get memory", /* ESPACE */ "bad back reference", /* ESUBREG */ "bad argument", /* INVARG */ "match failed" /* NOMATCH */ }; /************************************************* * Translate error code to string * *************************************************/ PCREPOSIX_EXP_DEFN size_t PCRE_CALL_CONVENTION regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) { const char *message, *addmessage; size_t length, addlength; message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))? "unknown error code" : pstring[errcode]; length = strlen(message) + 1; addmessage = " at offset "; addlength = (preg != NULL && (int)preg->re_erroffset != -1)? strlen(addmessage) + 6 : 0; if (errbuf_size > 0) { if (addlength > 0 && errbuf_size >= length + addlength) sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset); else { strncpy(errbuf, message, errbuf_size - 1); errbuf[errbuf_size-1] = 0; } } return length + addlength; } /************************************************* * Free store held by a regex * *************************************************/ PCREPOSIX_EXP_DEFN void PCRE_CALL_CONVENTION regfree(regex_t *preg) { (PUBL(free))(preg->re_pcre); } /************************************************* * Compile a regular expression * *************************************************/ /* Arguments: preg points to a structure for recording the compiled expression pattern the pattern to compile cflags compilation flags Returns: 0 on success various non-zero codes on failure */ PCREPOSIX_EXP_DEFN int PCRE_CALL_CONVENTION regcomp(regex_t *preg, const char *pattern, int cflags) { const char *errorptr; int erroffset; int errorcode; int options = 0; if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS; if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE; if ((cflags & REG_DOTALL) != 0) options |= PCRE_DOTALL; if ((cflags & REG_NOSUB) != 0) options |= PCRE_NO_AUTO_CAPTURE; if ((cflags & REG_UTF8) != 0) options |= PCRE_UTF8; if ((cflags & REG_UCP) != 0) options |= PCRE_UCP; if ((cflags & REG_UNGREEDY) != 0) options |= PCRE_UNGREEDY; preg->re_pcre = pcre_compile2(pattern, options, &errorcode, &errorptr, &erroffset, NULL); preg->re_erroffset = erroffset; /* Safety: if the error code is too big for the translation vector (which should not happen, but we all make mistakes), return REG_BADPAT. */ if (preg->re_pcre == NULL) { return (errorcode < (int)(sizeof(eint)/sizeof(const int)))? eint[errorcode] : REG_BADPAT; } (void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT, &(preg->re_nsub)); return 0; } /************************************************* * Match a regular expression * *************************************************/ /* Unfortunately, PCRE requires 3 ints of working space for each captured substring, so we have to get and release working store instead of just using the POSIX structures as was done in earlier releases when PCRE needed only 2 ints. However, if the number of possible capturing brackets is small, use a block of store on the stack, to reduce the use of malloc/free. The threshold is in a macro that can be changed at configure time. If REG_NOSUB was specified at compile time, the PCRE_NO_AUTO_CAPTURE flag will be set. When this is the case, the nmatch and pmatch arguments are ignored, and the only result is yes/no/error. */ PCREPOSIX_EXP_DEFN int PCRE_CALL_CONVENTION regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { int rc, so, eo; int options = 0; int *ovector = NULL; int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; BOOL allocated_ovector = FALSE; BOOL nosub = (((const pcre *)preg->re_pcre)->options & PCRE_NO_AUTO_CAPTURE) != 0; if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL; if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL; if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE_NOTEMPTY; ((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ /* When no string data is being returned, or no vector has been passed in which to put it, ensure that nmatch is zero. Otherwise, ensure the vector for holding the return data is large enough. */ if (nosub || pmatch == NULL) nmatch = 0; else if (nmatch > 0) { if (nmatch <= POSIX_MALLOC_THRESHOLD) { ovector = &(small_ovector[0]); } else { if (nmatch > INT_MAX/(sizeof(int) * 3)) return REG_ESPACE; ovector = (int *)malloc(sizeof(int) * nmatch * 3); if (ovector == NULL) return REG_ESPACE; allocated_ovector = TRUE; } } /* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings. The man page from OS X says "REG_STARTEND affects only the location of the string, not how it is matched". That is why the "so" value is used to bump the start location rather than being passed as a PCRE "starting offset". */ if ((eflags & REG_STARTEND) != 0) { so = pmatch[0].rm_so; eo = pmatch[0].rm_eo; } else { so = 0; eo = (int)strlen(string); } rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string + so, (eo - so), 0, options, ovector, (int)(nmatch * 3)); if (rc == 0) rc = (int)nmatch; /* All captured slots were filled in */ /* Successful match */ if (rc >= 0) { size_t i; if (!nosub) { for (i = 0; i < (size_t)rc; i++) { pmatch[i].rm_so = ovector[i*2]; pmatch[i].rm_eo = ovector[i*2+1]; } if (allocated_ovector) free(ovector); for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; } return 0; } /* Unsuccessful match */ if (allocated_ovector) free(ovector); switch(rc) { /* ========================================================================== */ /* These cases are never obeyed. This is a fudge that causes a compile-time error if the vector eint, which is indexed by compile-time error number, is not the correct length. It seems to be the only way to do such a check at compile time, as the sizeof() operator does not work in the C preprocessor. As all the PCRE_ERROR_xxx values are negative, we can use 0 and 1. */ case 0: case (sizeof(eint)/sizeof(int) == ERRCOUNT): return REG_ASSERT; /* ========================================================================== */ case PCRE_ERROR_NOMATCH: return REG_NOMATCH; case PCRE_ERROR_NULL: return REG_INVARG; case PCRE_ERROR_BADOPTION: return REG_INVARG; case PCRE_ERROR_BADMAGIC: return REG_INVARG; case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT; case PCRE_ERROR_NOMEMORY: return REG_ESPACE; case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE; case PCRE_ERROR_BADUTF8: return REG_INVARG; case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG; case PCRE_ERROR_BADMODE: return REG_INVARG; default: return REG_ASSERT; } } /* End of pcreposix.c */ pcre-8.31/pcreposix.h0000644000222100022210000001251411676645217011512 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ #ifndef _PCREPOSIX_H #define _PCREPOSIX_H /* This is the header for the POSIX wrapper interface to the PCRE Perl- Compatible Regular Expression library. It defines the things POSIX says should be there. I hope. Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Have to include stdlib.h in order to ensure that size_t is defined. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options, mostly defined by POSIX, but with some extras. */ #define REG_ICASE 0x0001 /* Maps to PCRE_CASELESS */ #define REG_NEWLINE 0x0002 /* Maps to PCRE_MULTILINE */ #define REG_NOTBOL 0x0004 /* Maps to PCRE_NOTBOL */ #define REG_NOTEOL 0x0008 /* Maps to PCRE_NOTEOL */ #define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE_DOTALL */ #define REG_NOSUB 0x0020 /* Maps to PCRE_NO_AUTO_CAPTURE */ #define REG_UTF8 0x0040 /* NOT defined by POSIX; maps to PCRE_UTF8 */ #define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */ #define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE_NOTEMPTY */ #define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE_UNGREEDY */ #define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE_UCP */ /* This is not used by PCRE, but by defining it we make it easier to slot PCRE into existing programs that make POSIX calls. */ #define REG_EXTENDED 0 /* Error values. Not all these are relevant or used by the wrapper. */ enum { REG_ASSERT = 1, /* internal error ? */ REG_BADBR, /* invalid repeat counts in {} */ REG_BADPAT, /* pattern error */ REG_BADRPT, /* ? * + invalid */ REG_EBRACE, /* unbalanced {} */ REG_EBRACK, /* unbalanced [] */ REG_ECOLLATE, /* collation error - not relevant */ REG_ECTYPE, /* bad class */ REG_EESCAPE, /* bad escape sequence */ REG_EMPTY, /* empty expression */ REG_EPAREN, /* unbalanced () */ REG_ERANGE, /* bad range inside [] */ REG_ESIZE, /* expression too big */ REG_ESPACE, /* failed to get memory */ REG_ESUBREG, /* bad back reference */ REG_INVARG, /* bad argument */ REG_NOMATCH /* match failed */ }; /* The structure representing a compiled regular expression. */ typedef struct { void *re_pcre; size_t re_nsub; size_t re_erroffset; } regex_t; /* The structure in which a captured offset is returned. */ typedef int regoff_t; typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t; /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export settings are needed, and are set in pcreposix.c before including this file. */ #if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL) # define PCREPOSIX_EXP_DECL extern __declspec(dllimport) # define PCREPOSIX_EXP_DEFN __declspec(dllimport) #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCREPOSIX_EXP_DECL # ifdef __cplusplus # define PCREPOSIX_EXP_DECL extern "C" # define PCREPOSIX_EXP_DEFN extern "C" # else # define PCREPOSIX_EXP_DECL extern # define PCREPOSIX_EXP_DEFN extern # endif #endif /* The functions */ PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int); PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t, regmatch_t *, int); PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t); PCREPOSIX_EXP_DECL void regfree(regex_t *); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcreposix.h */ pcre-8.31/CheckMan0000755000222100022210000000272411513102245010701 00000000000000#! /usr/bin/perl # A script to scan PCRE's man pages to check for typos in the control # sequences. I use only a small set of the available repertoire, so it is # straightforward to check that nothing else has slipped in by mistake. This # script should be called in the doc directory. $yield = 0; while (scalar(@ARGV) > 0) { $line = 0; $file = shift @ARGV; open (IN, $file) || die "Failed to open $file\n"; while () { $line++; if (/^\s*$/) { printf "Empty line $line of $file\n"; $yield = 1; } elsif (/^\./) { if (!/^\.\s*$| ^\.B\s+\S| ^\.TH\s\S| ^\.SH\s\S| ^\.SS\s\S| ^\.TP(?:\s\d+)?\s*$| ^\.ti\s\S| ^\.SM\s*$| ^\.rs\s*$| ^\.sp\s*$| ^\.nf\s*$| ^\.fi\s*$| ^\.P\s*$| ^\.PP\s*$| ^\.\\"(?:\ HREF)?\s*$| ^\.\\"\sHTML\s\s*$| ^\.\\"\sHTML\s<\/a>\s*$| ^\.\\"\s<\/a>\s*$| ^\.\\"\sJOINSH\s*$| ^\.\\"\sJOIN\s*$/x ) { printf "Bad control line $line of $file\n"; $yield = 1; } } else { if (/\\[^ef]|\\f[^IBP]/) { printf "Bad backslash in line $line of $file\n"; $yield = 1; } } } close(IN); } exit $yield; # End pcre-8.31/pcre.h.in0000644000222100022210000005557111744035262011033 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The current PCRE version information. */ #define PCRE_MAJOR @PCRE_MAJOR@ #define PCRE_MINOR @PCRE_MINOR@ #define PCRE_PRERELEASE @PCRE_PRERELEASE@ #define PCRE_DATE @PCRE_DATE@ /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export setting is defined in pcre_internal.h, which includes this file. So we don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # ifndef PCRE_EXP_DECL # define PCRE_EXP_DECL extern __declspec(dllimport) # endif # ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern __declspec(dllimport) # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN __declspec(dllimport) # endif # endif #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCRE_EXP_DECL # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif #endif #ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN # endif #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options. Some are compile-time only, some are run-time only, and some are both, so we keep them all distinct. However, almost all the bits in the options word are now used. In the long run, we may have to re-use some of the compile-time only bits for runtime options, or vice versa. In the comments below, "compile", "exec", and "DFA exec" mean that the option is permitted to be set for those functions; "used in" means that an option may be set only for compile, but is subsequently referenced in exec and/or DFA exec. Any of the compile-time options may be inspected during studying (and therefore JIT compiling). */ #define PCRE_CASELESS 0x00000001 /* Compile */ #define PCRE_MULTILINE 0x00000002 /* Compile */ #define PCRE_DOTALL 0x00000004 /* Compile */ #define PCRE_EXTENDED 0x00000008 /* Compile */ #define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */ #define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */ #define PCRE_EXTRA 0x00000040 /* Compile */ #define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */ #define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */ #define PCRE_UNGREEDY 0x00000200 /* Compile */ #define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */ /* The next two are also used in exec and DFA exec */ #define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */ #define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */ #define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ /* The next two are also used in exec and DFA exec */ #define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */ #define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */ #define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ #define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */ #define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ #define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */ #define PCRE_DFA_RESTART 0x00020000 /* DFA exec */ #define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */ #define PCRE_DUPNAMES 0x00080000 /* Compile */ #define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */ #define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */ #define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */ #define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */ #define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */ #define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */ #define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */ #define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */ #define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */ /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_OPCODE (-5) #define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */ #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) #define PCRE_ERROR_DFA_UITEM (-16) #define PCRE_ERROR_DFA_UCOND (-17) #define PCRE_ERROR_DFA_UMLIMIT (-18) #define PCRE_ERROR_DFA_WSSIZE (-19) #define PCRE_ERROR_DFA_RECURSE (-20) #define PCRE_ERROR_RECURSIONLIMIT (-21) #define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ #define PCRE_ERROR_BADNEWLINE (-23) #define PCRE_ERROR_BADOFFSET (-24) #define PCRE_ERROR_SHORTUTF8 (-25) #define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */ #define PCRE_ERROR_RECURSELOOP (-26) #define PCRE_ERROR_JIT_STACKLIMIT (-27) #define PCRE_ERROR_BADMODE (-28) #define PCRE_ERROR_BADENDIANNESS (-29) #define PCRE_ERROR_DFA_BADRESTART (-30) /* Specific error codes for UTF-8 validity checks */ #define PCRE_UTF8_ERR0 0 #define PCRE_UTF8_ERR1 1 #define PCRE_UTF8_ERR2 2 #define PCRE_UTF8_ERR3 3 #define PCRE_UTF8_ERR4 4 #define PCRE_UTF8_ERR5 5 #define PCRE_UTF8_ERR6 6 #define PCRE_UTF8_ERR7 7 #define PCRE_UTF8_ERR8 8 #define PCRE_UTF8_ERR9 9 #define PCRE_UTF8_ERR10 10 #define PCRE_UTF8_ERR11 11 #define PCRE_UTF8_ERR12 12 #define PCRE_UTF8_ERR13 13 #define PCRE_UTF8_ERR14 14 #define PCRE_UTF8_ERR15 15 #define PCRE_UTF8_ERR16 16 #define PCRE_UTF8_ERR17 17 #define PCRE_UTF8_ERR18 18 #define PCRE_UTF8_ERR19 19 #define PCRE_UTF8_ERR20 20 #define PCRE_UTF8_ERR21 21 /* Specific error codes for UTF-16 validity checks */ #define PCRE_UTF16_ERR0 0 #define PCRE_UTF16_ERR1 1 #define PCRE_UTF16_ERR2 2 #define PCRE_UTF16_ERR3 3 #define PCRE_UTF16_ERR4 4 /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 #define PCRE_INFO_OKPARTIAL 12 #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 #define PCRE_INFO_MINLENGTH 15 #define PCRE_INFO_JIT 16 #define PCRE_INFO_JITSIZE 17 #define PCRE_INFO_MAXLOOKBEHIND 18 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 #define PCRE_CONFIG_BSR 8 #define PCRE_CONFIG_JIT 9 #define PCRE_CONFIG_UTF16 10 #define PCRE_CONFIG_JITTARGET 11 /* Request types for pcre_study(). Do not re-arrange, in order to remain compatible. */ #define PCRE_STUDY_JIT_COMPILE 0x0001 #define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 #define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 /* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 #define PCRE_EXTRA_MARK 0x0020 #define PCRE_EXTRA_EXECUTABLE_JIT 0x0040 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; struct real_pcre16; /* declaration; the definition is private */ typedef struct real_pcre16 pcre16; struct real_pcre_jit_stack; /* declaration; the definition is private */ typedef struct real_pcre_jit_stack pcre_jit_stack; struct real_pcre16_jit_stack; /* declaration; the definition is private */ typedef struct real_pcre16_jit_stack pcre16_jit_stack; /* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain a 16 bit wide signed data type. Otherwise it can be a dummy data type since pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */ #ifndef PCRE_UCHAR16 #define PCRE_UCHAR16 unsigned short #endif #ifndef PCRE_SPTR16 #define PCRE_SPTR16 const PCRE_UCHAR16 * #endif /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ #ifndef PCRE_SPTR #define PCRE_SPTR const char * #endif /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ unsigned char **mark; /* For passing back a mark pointer */ void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre_extra; /* Same structure as above, but with 16 bit char pointers. */ typedef struct pcre16_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ PCRE_UCHAR16 **mark; /* For passing back a mark pointer */ void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre16_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------- Added for Version 2 -------------------------- */ const unsigned char *mark; /* Pointer to current mark or NULL */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Same structure as above, but with 16 bit char pointers. */ typedef struct pcre16_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR16 subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------- Added for Version 2 -------------------------- */ const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */ /* ------------------------------------------------------------------ */ } pcre16_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. For Virtual Pascal, these definitions have to take another form. */ #ifndef VPCOMPAT PCRE_EXP_DECL void *(*pcre_malloc)(size_t); PCRE_EXP_DECL void (*pcre_free)(void *); PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); PCRE_EXP_DECL void *(*pcre16_malloc)(size_t); PCRE_EXP_DECL void (*pcre16_free)(void *); PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre16_stack_free)(void *); PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); PCRE_EXP_DECL void *pcre16_malloc(size_t); PCRE_EXP_DECL void pcre16_free(void *); PCRE_EXP_DECL void *pcre16_stack_malloc(size_t); PCRE_EXP_DECL void pcre16_stack_free(void *); PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *); #endif /* VPCOMPAT */ /* User defined callback which provides a stack just before the match starts. */ typedef pcre_jit_stack *(*pcre_jit_callback)(void *); typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); PCRE_EXP_DECL int pcre16_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, int); PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int, PCRE_UCHAR16 *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *, PCRE_SPTR16, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *, PCRE_SPTR16, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); PCRE_EXP_DECL void pcre_free_substring_list(const char **); PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int, void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16, int *, int, PCRE_SPTR16, PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16, PCRE_UCHAR16 **, PCRE_UCHAR16 **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int, PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, PCRE_SPTR16 **); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **); PCRE_EXP_DECL void pcre_free_study(pcre_extra *); PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); PCRE_EXP_DECL const char *pcre_version(void); PCRE_EXP_DECL const char *pcre16_version(void); /* Utility functions for byte order swaps. */ PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *, const unsigned char *); PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *, const unsigned char *); PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, PCRE_SPTR16, int, int *, int); /* JIT compiler related functions. */ PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int); PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *); PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, pcre_jit_callback, void *); PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, pcre16_jit_callback, void *); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ pcre-8.31/NON-AUTOTOOLS-BUILD0000644000222100022210000005715011770363601012120 00000000000000Building PCRE without using autotools ------------------------------------- This document contains the following sections: General Generic instructions for the PCRE C library The C++ wrapper functions Building for virtual Pascal Stack size in Windows environments Linking programs in Windows environments Comments about Win32 builds Building PCRE on Windows with CMake Use of relative paths with CMake on Windows Testing with RunTest.bat Building under Windows with BCC5.5 Building PCRE on OpenVMS Building PCRE on Stratus OpenVOS GENERAL I (Philip Hazel) have no experience of Windows or VMS sytems and how their libraries work. The items in the PCRE distribution and Makefile that relate to anything other than Linux systems are untested by me. There are some other comments and files (including some documentation in CHM format) in the Contrib directory on the FTP site: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib The basic PCRE library consists entirely of code written in Standard C, and so should compile successfully on any system that has a Standard C compiler and library. The C++ wrapper functions are a separate issue (see below). The PCRE distribution includes a "configure" file for use by the configure/make (autotools) build system, as found in many Unix-like environments. The README file contains information about the options for "configure". There is also support for CMake, which some users prefer, especially in Windows environments, though it can also be run in Unix-like environments. See the section entitled "Building PCRE on Windows with CMake" below. Versions of config.h and pcre.h are distributed in the PCRE tarballs under the names config.h.generic and pcre.h.generic. These are provided for those who build PCRE without using "configure" or CMake. If you use "configure" or CMake, the .generic versions are not used. GENERIC INSTRUCTIONS FOR THE PCRE C LIBRARY The following are generic instructions for building the PCRE C library "by hand": (1) Copy or rename the file config.h.generic as config.h, and edit the macro settings that it contains to whatever is appropriate for your environment. In particular, if you want to force a specific value for newline, you can define the NEWLINE macro. When you compile any of the PCRE modules, you must specify -DHAVE_CONFIG_H to your compiler so that config.h is included in the sources. An alternative approach is not to edit config.h, but to use -D on the compiler command line to make any changes that you need to the configuration options. In this case -DHAVE_CONFIG_H must not be set. NOTE: There have been occasions when the way in which certain parameters in config.h are used has changed between releases. (In the configure/make world, this is handled automatically.) When upgrading to a new release, you are strongly advised to review config.h.generic before re-using what you had previously. (2) Copy or rename the file pcre.h.generic as pcre.h. (3) EITHER: Copy or rename file pcre_chartables.c.dist as pcre_chartables.c. OR: Compile dftables.c as a stand-alone program (using -DHAVE_CONFIG_H if you have set up config.h), and then run it with the single argument "pcre_chartables.c". This generates a set of standard character tables and writes them to that file. The tables are generated using the default C locale for your system. If you want to use a locale that is specified by LC_xxx environment variables, add the -L option to the dftables command. You must use this method if you are building on a system that uses EBCDIC code. The tables in pcre_chartables.c are defaults. The caller of PCRE can specify alternative tables at run time. (4) Ensure that you have the following header files: pcre_internal.h ucp.h (5) For an 8-bit library, compile the following source files, setting -DHAVE_CONFIG_H as a compiler option if you have set up config.h with your configuration, or else use other -D settings to change the configuration as required. pcre_byte_order.c pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_maketables.c pcre_newline.c pcre_ord2utf8.c pcre_refcount.c pcre_string_utils.c pcre_study.c pcre_tables.c pcre_ucd.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c Make sure that you include -I. in the compiler command (or equivalent for an unusual compiler) so that all included PCRE header files are first sought in the current directory. Otherwise you run the risk of picking up a previously-installed file from somewhere else. (6) If you have defined SUPPORT_JIT in config.h, you must also compile pcre_jit_compile.c This file #includes sources from the sljit subdirectory, where there should be 16 files, all of whose names begin with "sljit". (7) Now link all the compiled code into an object library in whichever form your system keeps such libraries. This is the basic PCRE C 8-bit library. If your system has static and shared libraries, you may have to do this once for each type. (8) If you want to build a 16-bit library (as well as, or instead of the 8-bit library) repeat steps 5-7 with the following files: pcre16_byte_order.c pcre16_chartables.c pcre16_compile.c pcre16_config.c pcre16_dfa_exec.c pcre16_exec.c pcre16_fullinfo.c pcre16_get.c pcre16_globals.c pcre16_jit_compile.c (if SUPPORT_JIT is defined) pcre16_maketables.c pcre16_newline.c pcre16_ord2utf16.c pcre16_refcount.c pcre16_string_utils.c pcre16_study.c pcre16_tables.c pcre16_ucd.c pcre16_utf16_utils.c pcre16_valid_utf16.c pcre16_version.c pcre16_xclass.c (9) If you want to build the POSIX wrapper functions (which apply only to the 8-bit library), ensure that you have the pcreposix.h file and then compile pcreposix.c (remembering -DHAVE_CONFIG_H if necessary). Link the result (on its own) as the pcreposix library. (10) The pcretest program can be linked with either or both of the 8-bit and 16-bit libraries (depending on what you selected in config.h). Compile pcretest.c and pcre_printint.c (again, don't forget -DHAVE_CONFIG_H) and link them together with the appropriate library/ies. If you compiled an 8-bit library, pcretest also needs the pcreposix wrapper library unless you compiled it with -DNOPOSIX. (11) Run pcretest on the testinput files in the testdata directory, and check that the output matches the corresponding testoutput files. There are comments about what each test does in the section entitled "Testing PCRE" in the README file. If you compiled both an 8-bit and a 16-bit library, you need to run pcretest with the -16 option to do 16-bit tests. Some tests are relevant only when certain build-time options are selected. For example, test 4 is for UTF-8 or UTF-16 support, and will not run if you have built PCRE without it. See the comments at the start of each testinput file. If you have a suitable Unix-like shell, the RunTest script will run the appropriate tests for you. Note that the supplied files are in Unix format, with just LF characters as line terminators. You may need to edit them to change this if your system uses a different convention. If you are using Windows, you probably should use the wintestinput3 file instead of testinput3 (and the corresponding output file). This is a locale test; wintestinput3 sets the locale to "french" rather than "fr_FR", and there some minor output differences. (12) If you have built PCRE with SUPPORT_JIT, the JIT features will be tested by the testdata files. However, you might also like to build and run the JIT test program, pcre_jit_test.c. (13) If you want to use the pcregrep command, compile and link pcregrep.c; it uses only the basic 8-bit PCRE library (it does not need the pcreposix library). THE C++ WRAPPER FUNCTIONS The PCRE distribution also contains some C++ wrapper functions and tests, applicable to the 8-bit library, which were contributed by Google Inc. On a system that can use "configure" and "make", the functions are automatically built into a library called pcrecpp. It should be straightforward to compile the .cc files manually on other systems. The files called xxx_unittest.cc are test programs for each of the corresponding xxx.cc files. BUILDING FOR VIRTUAL PASCAL A script for building PCRE using Borland's C++ compiler for use with VPASCAL was contributed by Alexander Tokarev. Stefan Weber updated the script and added additional files. The following files in the distribution are for building PCRE for use with VP/Borland: makevp_c.txt, makevp_l.txt, makevp.bat, pcregexp.pas. STACK SIZE IN WINDOWS ENVIRONMENTS The default processor stack size of 1Mb in some Windows environments is too small for matching patterns that need much recursion. In particular, test 2 may fail because of this. Normally, running out of stack causes a crash, but there have been cases where the test program has just died silently. See your linker documentation for how to increase stack size if you experience problems. The Linux default of 8Mb is a reasonable choice for the stack, though even that can be too small for some pattern/subject combinations. PCRE has a compile configuration option to disable the use of stack for recursion so that heap is used instead. However, pattern matching is significantly slower when this is done. There is more about stack usage in the "pcrestack" documentation. LINKING PROGRAMS IN WINDOWS ENVIRONMENTS If you want to statically link a program against a PCRE library in the form of a non-dll .a file, you must define PCRE_STATIC before including pcre.h or pcrecpp.h, otherwise the pcre_malloc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. CALLING CONVENTIONS IN WINDOWS ENVIRONMENTS It is possible to compile programs to use different calling conventions using MSVC. Search the web for "calling conventions" for more information. To make it easier to change the calling convention for the exported functions in the PCRE library, the macro PCRE_CALL_CONVENTION is present in all the external definitions. It can be set externally when compiling (e.g. in CFLAGS). If it is not set, it defaults to empty; the default calling convention is then used (which is what is wanted most of the time). COMMENTS ABOUT WIN32 BUILDS (see also "BUILDING PCRE ON WINDOWS WITH CMAKE") There are two ways of building PCRE using the "configure, make, make install" paradigm on Windows systems: using MinGW or using Cygwin. These are not at all the same thing; they are completely different from each other. There is also support for building using CMake, which some users find a more straightforward way of building PCRE under Windows. The MinGW home page (http://www.mingw.org/) says this: MinGW: A collection of freely available and freely distributable Windows specific header files and import libraries combined with GNU toolsets that allow one to produce native Windows programs that do not rely on any 3rd-party C runtime DLLs. The Cygwin home page (http://www.cygwin.com/) says this: Cygwin is a Linux-like environment for Windows. It consists of two parts: . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing substantial Linux API functionality . A collection of tools which provide Linux look and feel. The Cygwin DLL currently works with all recent, commercially released x86 32 bit and 64 bit versions of Windows, with the exception of Windows CE. On both MinGW and Cygwin, PCRE should build correctly using: ./configure && make && make install This should create two libraries called libpcre and libpcreposix, and, if you have enabled building the C++ wrapper, a third one called libpcrecpp. These are independent libraries: when you link with libpcreposix or libpcrecpp you must also link with libpcre, which contains the basic functions. (Some earlier releases of PCRE included the basic libpcre functions in libpcreposix. This no longer happens.) A user submitted a special-purpose patch that makes it easy to create "pcre.dll" under mingw32 using the "msys" environment. It provides "pcre.dll" as a special target. If you use this target, no other files are built, and in particular, the pcretest and pcregrep programs are not built. An example of how this might be used is: ./configure --enable-utf --disable-cpp CFLAGS="-03 -s"; make pcre.dll Using Cygwin's compiler generates libraries and executables that depend on cygwin1.dll. If a library that is generated this way is distributed, cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL licence, this forces not only PCRE to be under the GPL, but also the entire application. A distributor who wants to keep their own code proprietary must purchase an appropriate Cygwin licence. MinGW has no such restrictions. The MinGW compiler generates a library or executable that can run standalone on Windows without any third party dll or licensing issues. But there is more complication: If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's gcc and MinGW's gcc). So, a user can: . Build native binaries by using MinGW or by getting Cygwin and using -mno-cygwin. . Build binaries that depend on cygwin1.dll by using Cygwin with the normal compiler flags. The test files that are supplied with PCRE are in UNIX format, with LF characters as line terminators. Unless your PCRE library uses a default newline option that includes LF as a valid newline, it may be necessary to change the line terminators in the test files to get some of the tests to work. BUILDING PCRE ON WINDOWS WITH CMAKE CMake is an alternative configuration facility that can be used instead of "configure". CMake creates project files (make files, solution files, etc.) tailored to numerous development environments, including Visual Studio, Borland, Msys, MinGW, NMake, and Unix. If possible, use short paths with no spaces in the names for your CMake installation and your PCRE source and build directories. The following instructions were contributed by a PCRE user. 1. Install the latest CMake version available from http://www.cmake.org/, and ensure that cmake\bin is on your path. 2. Unzip (retaining folder structure) the PCRE source tree into a source directory such as C:\pcre. You should ensure your local date and time is not earlier than the file dates in your source dir if the release is very new. 3. Create a new, empty build directory, preferably a subdirectory of the source dir. For example, C:\pcre\pcre-xx\build. 4. Run cmake-gui from the Shell envirornment of your build tool, for example, Msys for Msys/MinGW or Visual Studio Command Prompt for VC/VC++. 5. Enter C:\pcre\pcre-xx and C:\pcre\pcre-xx\build for the source and build directories, respectively. 6. Hit the "Configure" button. 7. Select the particular IDE / build tool that you are using (Visual Studio, MSYS makefiles, MinGW makefiles, etc.) 8. The GUI will then list several configuration options. This is where you can enable UTF-8 support or other PCRE optional features. 9. Hit "Configure" again. The adjacent "Generate" button should now be active. 10. Hit "Generate". 11. The build directory should now contain a usable build system, be it a solution file for Visual Studio, makefiles for MinGW, etc. Exit from cmake-gui and use the generated build system with your compiler or IDE. E.g., for MinGW you can run "make", or for Visual Studio, open the PCRE solution, select the desired configuration (Debug, or Release, etc.) and build the ALL_BUILD project. 12. If during configuration with cmake-gui you've elected to build the test programs, you can execute them by building the test project. E.g., for MinGW: "make test"; for Visual Studio build the RUN_TESTS project. The most recent build configuration is targeted by the tests. A summary of test results is presented. Complete test output is subsequently available for review in Testing\Temporary under your build dir. USE OF RELATIVE PATHS WITH CMAKE ON WINDOWS A PCRE user comments as follows: I thought that others may want to know the current state of CMAKE_USE_RELATIVE_PATHS support on Windows. Here it is: -- AdditionalIncludeDirectories is only partially modified (only the first path - see below) -- Only some of the contained file paths are modified - shown below for pcre.vcproj -- It properly modifies I am sure CMake people can fix that if they want to. Until then one will need to replace existing absolute paths in project files with relative paths manually (e.g. from VS) - relative to project file location. I did just that before being told to try CMAKE_USE_RELATIVE_PATHS. Not a big deal. AdditionalIncludeDirectories="E:\builds\pcre\build;E:\builds\pcre\pcre-7.5;" AdditionalIncludeDirectories=".;E:\builds\pcre\pcre-7.5;" RelativePath="pcre.h"> RelativePath="pcre_chartables.c"> RelativePath="pcre_chartables.c.rule"> TESTING WITH RUNTEST.BAT If configured with CMake, building the test project ("make test" or building ALL_TESTS in Visual Studio) creates (and runs) pcre_test.bat (and depending on your configuration options, possibly other test programs) in the build directory. Pcre_test.bat runs RunTest.Bat with correct source and exe paths. For manual testing with RunTest.bat, provided the build dir is a subdirectory of the source directory: Open command shell window. Chdir to the location of your pcretest.exe and pcregrep.exe programs. Call RunTest.bat with "..\RunTest.Bat" or "..\..\RunTest.bat" as appropriate. To run only a particular test with RunTest.Bat provide a test number argument. Otherwise: 1. Copy RunTest.bat into the directory where pcretest.exe and pcregrep.exe have been created. 2. Edit RunTest.bat to indentify the full or relative location of the pcre source (wherein which the testdata folder resides), e.g.: set srcdir=C:\pcre\pcre-8.20 3. In a Windows command environment, chdir to the location of your bat and exe programs. 4. Run RunTest.bat. Test outputs will automatically be compared to expected results, and discrepancies will be identified in the console output. To independently test the just-in-time compiler, run pcre_jit_test.exe. To test pcrecpp, run pcrecpp_unittest.exe, pcre_stringpiece_unittest.exe and pcre_scanner_unittest.exe. BUILDING UNDER WINDOWS WITH BCC5.5 Michael Roy sent these comments about building PCRE under Windows with BCC5.5: Some of the core BCC libraries have a version of PCRE from 1998 built in, which can lead to pcre_exec() giving an erroneous PCRE_ERROR_NULL from a version mismatch. I'm including an easy workaround below, if you'd like to include it in the non-unix instructions: When linking a project with BCC5.5, pcre.lib must be included before any of the libraries cw32.lib, cw32i.lib, cw32mt.lib, and cw32mti.lib on the command line. BUILDING UNDER WINDOWS CE WITH VISUAL STUDIO 200x Vincent Richomme sent a zip archive of files to help with this process. They can be found in the file "pcre-vsbuild.zip" in the Contrib directory of the FTP site. BUILDING PCRE ON OPENVMS Dan Mooney sent the following comments about building PCRE on OpenVMS. They relate to an older version of PCRE that used fewer source files, so the exact commands will need changing. See the current list of source files above. "It was quite easy to compile and link the library. I don't have a formal make file but the attached file [reproduced below] contains the OpenVMS DCL commands I used to build the library. I had to add #define POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere. The library was built on: O/S: HP OpenVMS v7.3-1 Compiler: Compaq C v6.5-001-48BCD Linker: vA13-01 The test results did not match 100% due to the issues you mention in your documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I modified some of the character tables temporarily and was able to get the results to match. Tests using the fr locale did not match since I don't have that locale loaded. The study size was always reported to be 3 less than the value in the standard test output files." ========================= $! This DCL procedure builds PCRE on OpenVMS $! $! I followed the instructions in the non-unix-use file in the distribution. $! $ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES $ COMPILE DFTABLES.C $ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ $ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C $ COMPILE MAKETABLES.C $ COMPILE GET.C $ COMPILE STUDY.C $! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol $! did not seem to be defined anywhere. $! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support. $ COMPILE PCRE.C $ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ $! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol $! did not seem to be defined anywhere. $ COMPILE PCREPOSIX.C $ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ $ COMPILE PCRETEST.C $ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB $! C programs that want access to command line arguments must be $! defined as a symbol $ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE" $! Arguments must be enclosed in quotes. $ PCRETEST "-C" $! Test results: $! $! The test results did not match 100%. The functions isprint(), iscntrl(), $! isgraph() and ispunct() on OpenVMS must not produce the same results $! as the system that built the test output files provided with the $! distribution. $! $! The study size did not match and was always 3 less on OpenVMS. $! $! Locale could not be set to fr $! ========================= BUILDING PCRE ON STRATUS OPENVOS These notes on the port of PCRE to VOS (lightly edited) were supplied by Ashutosh Warikoo, whose email address has the local part awarikoo and the domain nse.co.in. The port was for version 7.9 in August 2009. 1. Building PCRE I built pcre on OpenVOS Release 17.0.1at using GNU Tools 3.4a without any problems. I used the following packages to build PCRE: ftp://ftp.stratus.com/pub/vos/posix/ga/posix.save.evf.gz Please read and follow the instructions that come with these packages. To start the build of pcre, from the root of the package type: ./build.sh 2. Installing PCRE Once you have successfully built PCRE, login to the SysAdmin group, switch to the root user, and type [ !create_dir (master_disk)>usr --if needed ] [ !create_dir (master_disk)>usr>local --if needed ] !gmake install This installs PCRE and its man pages into /usr/local. You can add (master_disk)>usr>local>bin to your command search paths, or if you are in BASH, add /usr/local/bin to the PATH environment variable. 4. Restrictions This port requires readline library optionally. However during the build I faced some yet unexplored errors while linking with readline. As it was an optional component I chose to disable it. 5. Known Problems I ran the test suite, but you will have to be your own judge of whether this command, and this port, suits your purposes. If you find any problems that appear to be related to the port itself, please let me know. Please see the build.log file in the root of the package also. ========================== Last Updated: 18 June 2012 pcre-8.31/depcomp0000755000222100022210000004426711775524614010711 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2009-04-28.21; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free # Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u="sed s,\\\\\\\\,/,g" depmode=msvisualcpp fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: pcre-8.31/pcre_scanner_unittest.cc0000644000222100022210000001222211557213355014221 00000000000000// Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Greg J. Badros // // Unittest for scanner, especially GetNextComments and GetComments() // functionality. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include /* for strchr */ #include #include #include "pcrecpp.h" #include "pcre_stringpiece.h" #include "pcre_scanner.h" #define FLAGS_unittest_stack_size 49152 // Dies with a fatal error if the two values are not equal. #define CHECK_EQ(a, b) do { \ if ( (a) != (b) ) { \ fprintf(stderr, "%s:%d: Check failed because %s != %s\n", \ __FILE__, __LINE__, #a, #b); \ exit(1); \ } \ } while (0) using std::vector; using pcrecpp::StringPiece; using pcrecpp::Scanner; static void TestScanner() { const char input[] = "\n" "alpha = 1; // this sets alpha\n" "bravo = 2; // bravo is set here\n" "gamma = 33; /* and here is gamma */\n"; const char *re = "(\\w+) = (\\d+);"; Scanner s(input); string var; int number; s.SkipCXXComments(); s.set_save_comments(true); vector comments; s.Consume(re, &var, &number); CHECK_EQ(var, "alpha"); CHECK_EQ(number, 1); CHECK_EQ(s.LineNumber(), 3); s.GetNextComments(&comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); comments.resize(0); s.Consume(re, &var, &number); CHECK_EQ(var, "bravo"); CHECK_EQ(number, 2); s.GetNextComments(&comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " // bravo is set here\n"); comments.resize(0); s.Consume(re, &var, &number); CHECK_EQ(var, "gamma"); CHECK_EQ(number, 33); s.GetNextComments(&comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " /* and here is gamma */\n"); comments.resize(0); s.GetComments(0, sizeof(input), &comments); CHECK_EQ(comments.size(), 3); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); CHECK_EQ(comments[1].as_string(), " // bravo is set here\n"); CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n"); comments.resize(0); s.GetComments(0, (int)(strchr(input, '/') - input), &comments); CHECK_EQ(comments.size(), 0); comments.resize(0); s.GetComments((int)(strchr(input, '/') - input - 1), sizeof(input), &comments); CHECK_EQ(comments.size(), 3); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); CHECK_EQ(comments[1].as_string(), " // bravo is set here\n"); CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n"); comments.resize(0); s.GetComments((int)(strchr(input, '/') - input - 1), (int)(strchr(input + 1, '\n') - input + 1), &comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); comments.resize(0); } static void TestBigComment() { string input; for (int i = 0; i < 1024; ++i) { char buf[1024]; // definitely big enough sprintf(buf, " # Comment %d\n", i); input += buf; } input += "name = value;\n"; Scanner s(input.c_str()); s.SetSkipExpression("\\s+|#.*\n"); string name; string value; s.Consume("(\\w+) = (\\w+);", &name, &value); CHECK_EQ(name, "name"); CHECK_EQ(value, "value"); } // TODO: also test scanner and big-comment in a thread with a // small stack size int main(int argc, char** argv) { TestScanner(); TestBigComment(); // Done printf("OK\n"); return 0; } pcre-8.31/pcre_stringpiece.h.in0000644000222100022210000001423611473713266013426 00000000000000// Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat // // A string like object that points into another piece of memory. // Useful for providing an interface that allows clients to easily // pass in either a "const char*" or a "string". // // Arghh! I wish C++ literals were automatically of type "string". #ifndef _PCRE_STRINGPIECE_H #define _PCRE_STRINGPIECE_H #include #include #include // for ostream forward-declaration #if @pcre_have_type_traits@ #define HAVE_TYPE_TRAITS #include #elif @pcre_have_bits_type_traits@ #define HAVE_TYPE_TRAITS #include #endif #include using std::memcmp; using std::strlen; using std::string; namespace pcrecpp { class PCRECPP_EXP_DEFN StringPiece { private: const char* ptr_; int length_; public: // We provide non-explicit singleton constructors so users can pass // in a "const char*" or a "string" wherever a "StringPiece" is // expected. StringPiece() : ptr_(NULL), length_(0) { } StringPiece(const char* str) : ptr_(str), length_(static_cast(strlen(ptr_))) { } StringPiece(const unsigned char* str) : ptr_(reinterpret_cast(str)), length_(static_cast(strlen(ptr_))) { } StringPiece(const string& str) : ptr_(str.data()), length_(static_cast(str.size())) { } StringPiece(const char* offset, int len) : ptr_(offset), length_(len) { } // data() may return a pointer to a buffer with embedded NULs, and the // returned buffer may or may not be null terminated. Therefore it is // typically a mistake to pass data() to a routine that expects a NUL // terminated string. Use "as_string().c_str()" if you really need to do // this. Or better yet, change your routine so it does not rely on NUL // termination. const char* data() const { return ptr_; } int size() const { return length_; } bool empty() const { return length_ == 0; } void clear() { ptr_ = NULL; length_ = 0; } void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; } void set(const char* str) { ptr_ = str; length_ = static_cast(strlen(str)); } void set(const void* buffer, int len) { ptr_ = reinterpret_cast(buffer); length_ = len; } char operator[](int i) const { return ptr_[i]; } void remove_prefix(int n) { ptr_ += n; length_ -= n; } void remove_suffix(int n) { length_ -= n; } bool operator==(const StringPiece& x) const { return ((length_ == x.length_) && (memcmp(ptr_, x.ptr_, length_) == 0)); } bool operator!=(const StringPiece& x) const { return !(*this == x); } #define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \ bool operator cmp (const StringPiece& x) const { \ int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \ return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \ } STRINGPIECE_BINARY_PREDICATE(<, <); STRINGPIECE_BINARY_PREDICATE(<=, <); STRINGPIECE_BINARY_PREDICATE(>=, >); STRINGPIECE_BINARY_PREDICATE(>, >); #undef STRINGPIECE_BINARY_PREDICATE int compare(const StringPiece& x) const { int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); if (r == 0) { if (length_ < x.length_) r = -1; else if (length_ > x.length_) r = +1; } return r; } string as_string() const { return string(data(), size()); } void CopyToString(string* target) const { target->assign(ptr_, length_); } // Does "this" start with "x" bool starts_with(const StringPiece& x) const { return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0)); } }; } // namespace pcrecpp // ------------------------------------------------------------------ // Functions used to create STL containers that use StringPiece // Remember that a StringPiece's lifetime had better be less than // that of the underlying string or char*. If it is not, then you // cannot safely store a StringPiece into an STL container // ------------------------------------------------------------------ #ifdef HAVE_TYPE_TRAITS // This makes vector really fast for some STL implementations template<> struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif // allow StringPiece to be logged std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece); #endif /* _PCRE_STRINGPIECE_H */ pcre-8.31/pcre_string_utils.c0000644000222100022210000001101711676645224013223 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains an internal function that is used to match an extended class. It is used by both pcre_exec() and pcre_def_exec(). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" #ifndef COMPILE_PCRE8 /************************************************* * Compare string utilities * *************************************************/ /* The following two functions compares two strings. Basically an strcmp for non 8 bit characters. Arguments: str1 first string str2 second string Returns: 0 if both string are equal (like strcmp), 1 otherwise */ int PRIV(strcmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2) { pcre_uchar c1; pcre_uchar c2; while (*str1 != '\0' || *str2 != '\0') { c1 = *str1++; c2 = *str2++; if (c1 != c2) return ((c1 > c2) << 1) - 1; } /* Both length and characters must be equal. */ return 0; } int PRIV(strcmp_uc_c8)(const pcre_uchar *str1, const char *str2) { const pcre_uint8 *ustr2 = (pcre_uint8 *)str2; pcre_uchar c1; pcre_uchar c2; while (*str1 != '\0' || *ustr2 != '\0') { c1 = *str1++; c2 = (pcre_uchar)*ustr2++; if (c1 != c2) return ((c1 > c2) << 1) - 1; } /* Both length and characters must be equal. */ return 0; } /* The following two functions compares two, fixed length strings. Basically an strncmp for non 8 bit characters. Arguments: str1 first string str2 second string num size of the string Returns: 0 if both string are equal (like strcmp), 1 otherwise */ int PRIV(strncmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2, unsigned int num) { pcre_uchar c1; pcre_uchar c2; while (num-- > 0) { c1 = *str1++; c2 = *str2++; if (c1 != c2) return ((c1 > c2) << 1) - 1; } /* Both length and characters must be equal. */ return 0; } int PRIV(strncmp_uc_c8)(const pcre_uchar *str1, const char *str2, unsigned int num) { const pcre_uint8 *ustr2 = (pcre_uint8 *)str2; pcre_uchar c1; pcre_uchar c2; while (num-- > 0) { c1 = *str1++; c2 = (pcre_uchar)*ustr2++; if (c1 != c2) return ((c1 > c2) << 1) - 1; } /* Both length and characters must be equal. */ return 0; } /* The following function returns with the length of a zero terminated string. Basically an strlen for non 8 bit characters. Arguments: str string Returns: length of the string */ unsigned int PRIV(strlen_uc)(const pcre_uchar *str) { unsigned int len = 0; while (*str++ != 0) len++; return len; } #endif /* COMPILE_PCRE8 */ /* End of pcre_string_utils.c */ pcre-8.31/pcrecpp.h0000644000222100022210000006364111317671615011132 00000000000000// Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat // Support for PCRE_XXX modifiers added by Giuseppe Maxia, July 2005 #ifndef _PCRECPP_H #define _PCRECPP_H // C++ interface to the pcre regular-expression library. RE supports // Perl-style regular expressions (with extensions like \d, \w, \s, // ...). // // ----------------------------------------------------------------------- // REGEXP SYNTAX: // // This module is part of the pcre library and hence supports its syntax // for regular expressions. // // The syntax is pretty similar to Perl's. For those not familiar // with Perl's regular expressions, here are some examples of the most // commonly used extensions: // // "hello (\\w+) world" -- \w matches a "word" character // "version (\\d+)" -- \d matches a digit // "hello\\s+world" -- \s matches any whitespace character // "\\b(\\w+)\\b" -- \b matches empty string at a word boundary // "(?i)hello" -- (?i) turns on case-insensitive matching // "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible // // ----------------------------------------------------------------------- // MATCHING INTERFACE: // // The "FullMatch" operation checks that supplied text matches a // supplied pattern exactly. // // Example: successful match // pcrecpp::RE re("h.*o"); // re.FullMatch("hello"); // // Example: unsuccessful match (requires full match): // pcrecpp::RE re("e"); // !re.FullMatch("hello"); // // Example: creating a temporary RE object: // pcrecpp::RE("h.*o").FullMatch("hello"); // // You can pass in a "const char*" or a "string" for "text". The // examples below tend to use a const char*. // // You can, as in the different examples above, store the RE object // explicitly in a variable or use a temporary RE object. The // examples below use one mode or the other arbitrarily. Either // could correctly be used for any of these examples. // // ----------------------------------------------------------------------- // MATCHING WITH SUB-STRING EXTRACTION: // // You can supply extra pointer arguments to extract matched subpieces. // // Example: extracts "ruby" into "s" and 1234 into "i" // int i; // string s; // pcrecpp::RE re("(\\w+):(\\d+)"); // re.FullMatch("ruby:1234", &s, &i); // // Example: does not try to extract any extra sub-patterns // re.FullMatch("ruby:1234", &s); // // Example: does not try to extract into NULL // re.FullMatch("ruby:1234", NULL, &i); // // Example: integer overflow causes failure // !re.FullMatch("ruby:1234567891234", NULL, &i); // // Example: fails because there aren't enough sub-patterns: // !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s); // // Example: fails because string cannot be stored in integer // !pcrecpp::RE("(.*)").FullMatch("ruby", &i); // // The provided pointer arguments can be pointers to any scalar numeric // type, or one of // string (matched piece is copied to string) // StringPiece (StringPiece is mutated to point to matched piece) // T (where "bool T::ParseFrom(const char*, int)" exists) // NULL (the corresponding matched sub-pattern is not copied) // // CAVEAT: An optional sub-pattern that does not exist in the matched // string is assigned the empty string. Therefore, the following will // return false (because the empty string is not a valid number): // int number; // pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number); // // ----------------------------------------------------------------------- // DO_MATCH // // The matching interface supports at most 16 arguments per call. // If you need more, consider using the more general interface // pcrecpp::RE::DoMatch(). See pcrecpp.h for the signature for DoMatch. // // ----------------------------------------------------------------------- // PARTIAL MATCHES // // You can use the "PartialMatch" operation when you want the pattern // to match any substring of the text. // // Example: simple search for a string: // pcrecpp::RE("ell").PartialMatch("hello"); // // Example: find first number in a string: // int number; // pcrecpp::RE re("(\\d+)"); // re.PartialMatch("x*100 + 20", &number); // assert(number == 100); // // ----------------------------------------------------------------------- // UTF-8 AND THE MATCHING INTERFACE: // // By default, pattern and text are plain text, one byte per character. // The UTF8 flag, passed to the constructor, causes both pattern // and string to be treated as UTF-8 text, still a byte stream but // potentially multiple bytes per character. In practice, the text // is likelier to be UTF-8 than the pattern, but the match returned // may depend on the UTF8 flag, so always use it when matching // UTF8 text. E.g., "." will match one byte normally but with UTF8 // set may match up to three bytes of a multi-byte character. // // Example: // pcrecpp::RE_Options options; // options.set_utf8(); // pcrecpp::RE re(utf8_pattern, options); // re.FullMatch(utf8_string); // // Example: using the convenience function UTF8(): // pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); // re.FullMatch(utf8_string); // // NOTE: The UTF8 option is ignored if pcre was not configured with the // --enable-utf8 flag. // // ----------------------------------------------------------------------- // PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE // // PCRE defines some modifiers to change the behavior of the regular // expression engine. // The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle // to pass such modifiers to a RE class. // // Currently, the following modifiers are supported // // modifier description Perl corresponding // // PCRE_CASELESS case insensitive match /i // PCRE_MULTILINE multiple lines match /m // PCRE_DOTALL dot matches newlines /s // PCRE_DOLLAR_ENDONLY $ matches only at end N/A // PCRE_EXTRA strict escape parsing N/A // PCRE_EXTENDED ignore whitespaces /x // PCRE_UTF8 handles UTF8 chars built-in // PCRE_UNGREEDY reverses * and *? N/A // PCRE_NO_AUTO_CAPTURE disables matching parens N/A (*) // // (For a full account on how each modifier works, please check the // PCRE API reference manual). // // (*) Both Perl and PCRE allow non matching parentheses by means of the // "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not // capture, while (ab|cd) does. // // For each modifier, there are two member functions whose name is made // out of the modifier in lowercase, without the "PCRE_" prefix. For // instance, PCRE_CASELESS is handled by // bool caseless(), // which returns true if the modifier is set, and // RE_Options & set_caseless(bool), // which sets or unsets the modifier. // // Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the // set_match_limit() and match_limit() member functions. // Setting match_limit to a non-zero value will limit the executation of // pcre to keep it from doing bad things like blowing the stack or taking // an eternity to return a result. A value of 5000 is good enough to stop // stack blowup in a 2MB thread stack. Setting match_limit to zero will // disable match limiting. Alternately, you can set match_limit_recursion() // which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much pcre // recurses. match_limit() caps the number of matches pcre does; // match_limit_recrusion() caps the depth of recursion. // // Normally, to pass one or more modifiers to a RE class, you declare // a RE_Options object, set the appropriate options, and pass this // object to a RE constructor. Example: // // RE_options opt; // opt.set_caseless(true); // // if (RE("HELLO", opt).PartialMatch("hello world")) ... // // RE_options has two constructors. The default constructor takes no // arguments and creates a set of flags that are off by default. // // The optional parameter 'option_flags' is to facilitate transfer // of legacy code from C programs. This lets you do // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); // // But new code is better off doing // RE(pattern, // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); // (See below) // // If you are going to pass one of the most used modifiers, there are some // convenience functions that return a RE_Options class with the // appropriate modifier already set: // CASELESS(), UTF8(), MULTILINE(), DOTALL(), EXTENDED() // // If you need to set several options at once, and you don't want to go // through the pains of declaring a RE_Options object and setting several // options, there is a parallel method that give you such ability on the // fly. You can concatenate several set_xxxxx member functions, since each // of them returns a reference to its class object. e.g.: to pass // PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one // statement, you may write // // RE(" ^ xyz \\s+ .* blah$", RE_Options() // .set_caseless(true) // .set_extended(true) // .set_multiline(true)).PartialMatch(sometext); // // ----------------------------------------------------------------------- // SCANNING TEXT INCREMENTALLY // // The "Consume" operation may be useful if you want to repeatedly // match regular expressions at the front of a string and skip over // them as they match. This requires use of the "StringPiece" type, // which represents a sub-range of a real string. Like RE, StringPiece // is defined in the pcrecpp namespace. // // Example: read lines of the form "var = value" from a string. // string contents = ...; // Fill string somehow // pcrecpp::StringPiece input(contents); // Wrap in a StringPiece // // string var; // int value; // pcrecpp::RE re("(\\w+) = (\\d+)\n"); // while (re.Consume(&input, &var, &value)) { // ...; // } // // Each successful call to "Consume" will set "var/value", and also // advance "input" so it points past the matched text. // // The "FindAndConsume" operation is similar to "Consume" but does not // anchor your match at the beginning of the string. For example, you // could extract all words from a string by repeatedly calling // pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) // // ----------------------------------------------------------------------- // PARSING HEX/OCTAL/C-RADIX NUMBERS // // By default, if you pass a pointer to a numeric value, the // corresponding text is interpreted as a base-10 number. You can // instead wrap the pointer with a call to one of the operators Hex(), // Octal(), or CRadix() to interpret the text in another base. The // CRadix operator interprets C-style "0" (base-8) and "0x" (base-16) // prefixes, but defaults to base-10. // // Example: // int a, b, c, d; // pcrecpp::RE re("(.*) (.*) (.*) (.*)"); // re.FullMatch("100 40 0100 0x40", // pcrecpp::Octal(&a), pcrecpp::Hex(&b), // pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); // will leave 64 in a, b, c, and d. // // ----------------------------------------------------------------------- // REPLACING PARTS OF STRINGS // // You can replace the first match of "pattern" in "str" with // "rewrite". Within "rewrite", backslash-escaped digits (\1 to \9) // can be used to insert text matching corresponding parenthesized // group from the pattern. \0 in "rewrite" refers to the entire // matching text. E.g., // // string s = "yabba dabba doo"; // pcrecpp::RE("b+").Replace("d", &s); // // will leave "s" containing "yada dabba doo". The result is true if // the pattern matches and a replacement occurs, or false otherwise. // // GlobalReplace() is like Replace(), except that it replaces all // occurrences of the pattern in the string with the rewrite. // Replacements are not subject to re-matching. E.g., // // string s = "yabba dabba doo"; // pcrecpp::RE("b+").GlobalReplace("d", &s); // // will leave "s" containing "yada dada doo". It returns the number // of replacements made. // // Extract() is like Replace(), except that if the pattern matches, // "rewrite" is copied into "out" (an additional argument) with // substitutions. The non-matching portions of "text" are ignored. // Returns true iff a match occurred and the extraction happened // successfully. If no match occurs, the string is left unaffected. #include #include #include // defines the Arg class // This isn't technically needed here, but we include it // anyway so folks who include pcrecpp.h don't have to. #include namespace pcrecpp { #define PCRE_SET_OR_CLEAR(b, o) \ if (b) all_options_ |= (o); else all_options_ &= ~(o); \ return *this #define PCRE_IS_SET(o) \ (all_options_ & o) == o /***** Compiling regular expressions: the RE class *****/ // RE_Options allow you to set options to be passed along to pcre, // along with other options we put on top of pcre. // Only 9 modifiers, plus match_limit and match_limit_recursion, // are supported now. class PCRECPP_EXP_DEFN RE_Options { public: // constructor RE_Options() : match_limit_(0), match_limit_recursion_(0), all_options_(0) {} // alternative constructor. // To facilitate transfer of legacy code from C programs // // This lets you do // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); // But new code is better off doing // RE(pattern, // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); RE_Options(int option_flags) : match_limit_(0), match_limit_recursion_(0), all_options_(option_flags) {} // we're fine with the default destructor, copy constructor, etc. // accessors and mutators int match_limit() const { return match_limit_; }; RE_Options &set_match_limit(int limit) { match_limit_ = limit; return *this; } int match_limit_recursion() const { return match_limit_recursion_; }; RE_Options &set_match_limit_recursion(int limit) { match_limit_recursion_ = limit; return *this; } bool caseless() const { return PCRE_IS_SET(PCRE_CASELESS); } RE_Options &set_caseless(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_CASELESS); } bool multiline() const { return PCRE_IS_SET(PCRE_MULTILINE); } RE_Options &set_multiline(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_MULTILINE); } bool dotall() const { return PCRE_IS_SET(PCRE_DOTALL); } RE_Options &set_dotall(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_DOTALL); } bool extended() const { return PCRE_IS_SET(PCRE_EXTENDED); } RE_Options &set_extended(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_EXTENDED); } bool dollar_endonly() const { return PCRE_IS_SET(PCRE_DOLLAR_ENDONLY); } RE_Options &set_dollar_endonly(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_DOLLAR_ENDONLY); } bool extra() const { return PCRE_IS_SET(PCRE_EXTRA); } RE_Options &set_extra(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_EXTRA); } bool ungreedy() const { return PCRE_IS_SET(PCRE_UNGREEDY); } RE_Options &set_ungreedy(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_UNGREEDY); } bool utf8() const { return PCRE_IS_SET(PCRE_UTF8); } RE_Options &set_utf8(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_UTF8); } bool no_auto_capture() const { return PCRE_IS_SET(PCRE_NO_AUTO_CAPTURE); } RE_Options &set_no_auto_capture(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_NO_AUTO_CAPTURE); } RE_Options &set_all_options(int opt) { all_options_ = opt; return *this; } int all_options() const { return all_options_ ; } // TODO: add other pcre flags private: int match_limit_; int match_limit_recursion_; int all_options_; }; // These functions return some common RE_Options static inline RE_Options UTF8() { return RE_Options().set_utf8(true); } static inline RE_Options CASELESS() { return RE_Options().set_caseless(true); } static inline RE_Options MULTILINE() { return RE_Options().set_multiline(true); } static inline RE_Options DOTALL() { return RE_Options().set_dotall(true); } static inline RE_Options EXTENDED() { return RE_Options().set_extended(true); } // Interface for regular expression matching. Also corresponds to a // pre-compiled regular expression. An "RE" object is safe for // concurrent use by multiple threads. class PCRECPP_EXP_DEFN RE { public: // We provide implicit conversions from strings so that users can // pass in a string or a "const char*" wherever an "RE" is expected. RE(const string& pat) { Init(pat, NULL); } RE(const string& pat, const RE_Options& option) { Init(pat, &option); } RE(const char* pat) { Init(pat, NULL); } RE(const char* pat, const RE_Options& option) { Init(pat, &option); } RE(const unsigned char* pat) { Init(reinterpret_cast(pat), NULL); } RE(const unsigned char* pat, const RE_Options& option) { Init(reinterpret_cast(pat), &option); } // Copy constructor & assignment - note that these are expensive // because they recompile the expression. RE(const RE& re) { Init(re.pattern_, &re.options_); } const RE& operator=(const RE& re) { if (this != &re) { Cleanup(); // This is the code that originally came from Google // Init(re.pattern_.c_str(), &re.options_); // This is the replacement from Ari Pollak Init(re.pattern_, &re.options_); } return *this; } ~RE(); // The string specification for this RE. E.g. // RE re("ab*c?d+"); // re.pattern(); // "ab*c?d+" const string& pattern() const { return pattern_; } // If RE could not be created properly, returns an error string. // Else returns the empty string. const string& error() const { return *error_; } /***** The useful part: the matching interface *****/ // This is provided so one can do pattern.ReplaceAll() just as // easily as ReplaceAll(pattern-text, ....) bool FullMatch(const StringPiece& text, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool PartialMatch(const StringPiece& text, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool Consume(StringPiece* input, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool FindAndConsume(StringPiece* input, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool Replace(const StringPiece& rewrite, string *str) const; int GlobalReplace(const StringPiece& rewrite, string *str) const; bool Extract(const StringPiece &rewrite, const StringPiece &text, string *out) const; // Escapes all potentially meaningful regexp characters in // 'unquoted'. The returned string, used as a regular expression, // will exactly match the original string. For example, // 1.5-2.0? // may become: // 1\.5\-2\.0\? // Note QuoteMeta behaves the same as perl's QuoteMeta function, // *except* that it escapes the NUL character (\0) as backslash + 0, // rather than backslash + NUL. static string QuoteMeta(const StringPiece& unquoted); /***** Generic matching interface *****/ // Type of match (TODO: Should be restructured as part of RE_Options) enum Anchor { UNANCHORED, // No anchoring ANCHOR_START, // Anchor at start only ANCHOR_BOTH // Anchor at start and end }; // General matching routine. Stores the length of the match in // "*consumed" if successful. bool DoMatch(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const* args, int n) const; // Return the number of capturing subpatterns, or -1 if the // regexp wasn't valid on construction. int NumberOfCapturingGroups() const; // The default value for an argument, to indicate the end of the argument // list. This must be used only in optional argument defaults. It should NOT // be passed explicitly. Some people have tried to use it like this: // // FullMatch(x, y, &z, no_arg, &w); // // This is a mistake, and will not work. static Arg no_arg; private: void Init(const string& pattern, const RE_Options* options); void Cleanup(); // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with // pairs of integers for the beginning and end positions of matched // text. The first pair corresponds to the entire matched text; // subsequent pairs correspond, in order, to parentheses-captured // matches. Returns the number of pairs (one more than the number of // the last subpattern with a match) if matching was successful // and zero if the match failed. // I.e. for RE("(foo)|(bar)|(baz)") it will return 2, 3, and 4 when matching // against "foo", "bar", and "baz" respectively. // When matching RE("(foo)|hello") against "hello", it will return 1. // But the values for all subpattern are filled in into "vec". int TryMatch(const StringPiece& text, int startpos, Anchor anchor, bool empty_ok, int *vec, int vecsize) const; // Append the "rewrite" string, with backslash subsitutions from "text" // and "vec", to string "out". bool Rewrite(string *out, const StringPiece& rewrite, const StringPiece& text, int *vec, int veclen) const; // internal implementation for DoMatch bool DoMatchImpl(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const args[], int n, int* vec, int vecsize) const; // Compile the regexp for the specified anchoring mode pcre* Compile(Anchor anchor); string pattern_; RE_Options options_; pcre* re_full_; // For full matches pcre* re_partial_; // For partial matches const string* error_; // Error indicator (or points to empty string) }; } // namespace pcrecpp #endif /* _PCRECPP_H */ pcre-8.31/pcre16_printint.c0000644000222100022210000000420311676645216012513 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_printint.c" /* End of pcre16_printint.c */ pcre-8.31/pcre_jit_test.c0000644000222100022210000015045011767400034012314 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Main Library written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge This JIT compiler regression test program was written by Zoltan Herczeg Copyright (c) 2010-2012 ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "pcre.h" #define PCRE_BUG 0x80000000 /* Letter characters: \xe6\x92\xad = 0x64ad = 25773 (kanji) Non-letter characters: \xc2\xa1 = 0xa1 = (Inverted Exclamation Mark) \xf3\xa9\xb7\x80 = 0xe9dc0 = 957888 \xed\xa0\x80 = 55296 = 0xd800 (Invalid UTF character) \xed\xb0\x80 = 56320 = 0xdc00 (Invalid UTF character) Newlines: \xc2\x85 = 0x85 = 133 (NExt Line = NEL) \xe2\x80\xa8 = 0x2028 = 8232 (Line Separator) Othercase pairs: \xc3\xa9 = 0xe9 = 233 (e') \xc3\x89 = 0xc9 = 201 (E') \xc3\xa1 = 0xe1 = 225 (a') \xc3\x81 = 0xc1 = 193 (A') \xc8\xba = 0x23a = 570 \xe2\xb1\xa5 = 0x2c65 = 11365 \xe1\xbd\xb8 = 0x1f78 = 8056 \xe1\xbf\xb8 = 0x1ff8 = 8184 \xf0\x90\x90\x80 = 0x10400 = 66560 \xf0\x90\x90\xa8 = 0x10428 = 66600 Mark property: \xcc\x8d = 0x30d = 781 Special: \xdf\xbf = 0x7ff = 2047 (highest 2 byte character) \xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character) \xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character) \xf0\x90\x80\x80 = 0x10000 = 65536 (lowest 4 byte character) \xf4\x8f\xbf\xbf = 0x10ffff = 1114111 (highest allowed utf character) */ static int regression_tests(void); int main(void) { int jit = 0; #ifdef SUPPORT_PCRE8 pcre_config(PCRE_CONFIG_JIT, &jit); #else pcre16_config(PCRE_CONFIG_JIT, &jit); #endif if (!jit) { printf("JIT must be enabled to run pcre_jit_test\n"); return 1; } return regression_tests(); } /* --------------------------------------------------------------------------------------- */ #if !(defined SUPPORT_PCRE8) && !(defined SUPPORT_PCRE16) #error SUPPORT_PCRE8 or SUPPORT_PCRE16 must be defined #endif #define MUA (PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF) #define MUAP (PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF | PCRE_UCP) #define CMUA (PCRE_CASELESS | PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF) #define CMUAP (PCRE_CASELESS | PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF | PCRE_UCP) #define MA (PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF) #define MAP (PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF | PCRE_UCP) #define CMA (PCRE_CASELESS | PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF) #define OFFSET_MASK 0x00ffff #define F_NO8 0x010000 #define F_NO16 0x020000 #define F_NOMATCH 0x040000 #define F_DIFF 0x080000 #define F_FORCECONV 0x100000 #define F_PROPERTY 0x200000 struct regression_test_case { int flags; int start_offset; const char *pattern; const char *input; }; static struct regression_test_case regression_test_cases[] = { /* Constant strings. */ { MUA, 0, "AbC", "AbAbC" }, { MUA, 0, "ACCEPT", "AACACCACCEACCEPACCEPTACCEPTT" }, { CMUA, 0, "aA#\xc3\xa9\xc3\x81", "aA#Aa#\xc3\x89\xc3\xa1" }, { MA, 0, "[^a]", "aAbB" }, { CMA, 0, "[^m]", "mMnN" }, { MA, 0, "a[^b][^#]", "abacd" }, { CMA, 0, "A[^B][^E]", "abacd" }, { CMUA, 0, "[^x][^#]", "XxBll" }, { MUA, 0, "[^a]", "aaa\xc3\xa1#Ab" }, { CMUA, 0, "[^A]", "aA\xe6\x92\xad" }, { MUA, 0, "\\W(\\W)?\\w", "\r\n+bc" }, { MUA, 0, "\\W(\\W)?\\w", "\n\r+bc" }, { MUA, 0, "\\W(\\W)?\\w", "\r\r+bc" }, { MUA, 0, "\\W(\\W)?\\w", "\n\n+bc" }, { MUA, 0, "[axd]", "sAXd" }, { CMUA, 0, "[axd]", "sAXd" }, { CMUA, 0 | F_NOMATCH, "[^axd]", "DxA" }, { MUA, 0, "[a-dA-C]", "\xe6\x92\xad\xc3\xa9.B" }, { MUA, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" }, { CMUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, { MUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, { MUA, 0, "[^a]", "\xc2\x80[]" }, { CMUA, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" }, { CMA, 0, "1a2b3c4", "1a2B3c51A2B3C4" }, { PCRE_CASELESS, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" }, { PCRE_CASELESS, 0, "\xfe", "\xff\xfc#\xfe\xfe" }, { PCRE_CASELESS, 0, "a1", "Aa1" }, { MA, 0, "\\Ca", "cda" }, { CMA, 0, "\\Ca", "CDA" }, { MA, 0 | F_NOMATCH, "\\Cx", "cda" }, { CMA, 0 | F_NOMATCH, "\\Cx", "CDA" }, { CMUAP, 0, "\xf0\x90\x90\x80\xf0\x90\x90\xa8", "\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, { CMUAP, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, { CMUAP, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, { CMUAP, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, /* Assertions. */ { MUA, 0, "\\b[^A]", "A_B#" }, { MA, 0 | F_NOMATCH, "\\b\\W", "\n*" }, { MUA, 0, "\\B[^,]\\b[^s]\\b", "#X" }, { MAP, 0, "\\B", "_\xa1" }, { MAP, 0, "\\b_\\b[,A]\\B", "_," }, { MUAP, 0, "\\b", "\xe6\x92\xad!" }, { MUAP, 0, "\\B", "_\xc2\xa1\xc3\xa1\xc2\x85" }, { MUAP, 0, "\\b[^A]\\B[^c]\\b[^_]\\B", "_\xc3\xa1\xe2\x80\xa8" }, { MUAP, 0, "\\b\\w+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, { MUA, 0 | F_NOMATCH, "\\b.", "\xcd\xbe" }, { CMUAP, 0, "\\By", "\xf0\x90\x90\xa8y" }, { MA, 0 | F_NOMATCH, "\\R^", "\n" }, { MA, 1 | F_NOMATCH, "^", "\n" }, { 0, 0, "^ab", "ab" }, { 0, 0 | F_NOMATCH, "^ab", "aab" }, { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "^a", "\r\raa\n\naa\r\naa" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF, 0, "^-", "\xe2\x80\xa8--\xc2\x85-\r\n-" }, { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "^-", "a--b--\x85--" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "^-", "a--\xe2\x80\xa8--" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "^-", "a--\xc2\x85--" }, { 0, 0, "ab$", "ab" }, { 0, 0 | F_NOMATCH, "ab$", "abab\n\n" }, { PCRE_DOLLAR_ENDONLY, 0 | F_NOMATCH, "ab$", "abab\r\n" }, { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "a$", "\r\raa\n\naa\r\naa" }, { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "a$", "aaa" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF, 0, "#$", "#\xc2\x85###\r#" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "#$", "#\xe2\x80\xa9" }, { PCRE_NOTBOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "^a", "aa\naa" }, { PCRE_NOTBOL | PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "^a", "aa\naa" }, { PCRE_NOTEOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "a$", "aa\naa" }, { PCRE_NOTEOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "a$", "aa\r\n" }, { PCRE_UTF8 | PCRE_DOLLAR_ENDONLY | PCRE_NEWLINE_ANY, 0 | F_PROPERTY, "\\p{Any}{2,}$", "aa\r\n" }, { PCRE_NOTEOL | PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "a$", "aa\naa" }, { PCRE_NEWLINE_CR, 0, ".\\Z", "aaa" }, { PCRE_NEWLINE_CR | PCRE_UTF8, 0, "a\\Z", "aaa\r" }, { PCRE_NEWLINE_CR, 0, ".\\Z", "aaa\n" }, { PCRE_NEWLINE_CRLF, 0, ".\\Z", "aaa\r" }, { PCRE_NEWLINE_CRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" }, { PCRE_NEWLINE_CRLF, 0, ".\\Z", "aaa\r\n" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r\n" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\xe2\x80\xa8" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r\n" }, { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, ".\\Z", "aaa\xc2\x85" }, { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, ".\\Z", "aaa\xe2\x80\xa8" }, { MA, 0, "\\Aa", "aaa" }, { MA, 1 | F_NOMATCH, "\\Aa", "aaa" }, { MA, 1, "\\Ga", "aaa" }, { MA, 1 | F_NOMATCH, "\\Ga", "aba" }, { MA, 0, "a\\z", "aaa" }, { MA, 0 | F_NOMATCH, "a\\z", "aab" }, /* Brackets. */ { MUA, 0, "(ab|bb|cd)", "bacde" }, { MUA, 0, "(?:ab|a)(bc|c)", "ababc" }, { MUA, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" }, { CMUA, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" }, { MUA, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" }, { MUA, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" }, /* Greedy and non-greedy ? operators. */ { MUA, 0, "(?:a)?a", "laab" }, { CMUA, 0, "(A)?A", "llaab" }, { MUA, 0, "(a)?\?a", "aab" }, /* ?? is the prefix of trygraphs in GCC. */ { MUA, 0, "(a)?a", "manm" }, { CMUA, 0, "(a|b)?\?d((?:e)?)", "ABABdx" }, { MUA, 0, "(a|b)?\?d((?:e)?)", "abcde" }, { MUA, 0, "((?:ab)?\?g|b(?:g(nn|d)?\?)?)?\?(?:n)?m", "abgnbgnnbgdnmm" }, /* Greedy and non-greedy + operators */ { MUA, 0, "(aa)+aa", "aaaaaaa" }, { MUA, 0, "(aa)+?aa", "aaaaaaa" }, { MUA, 0, "(?:aba|ab|a)+l", "ababamababal" }, { MUA, 0, "(?:aba|ab|a)+?l", "ababamababal" }, { MUA, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, { MUA, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, { MUA, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" }, /* Greedy and non-greedy * operators */ { CMUA, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" }, { MUA, 0, "(?:aa)*?ab", "aaaaaaamaaaaaaab" }, { MUA, 0, "(aa|ab)*ab", "aaabaaab" }, { CMUA, 0, "(aa|Ab)*?aB", "aaabaaab" }, { MUA, 0, "(a|b)*(?:a)*(?:b)*m", "abbbaaababanabbbaaababamm" }, { MUA, 0, "(a|b)*?(?:a)*?(?:b)*?m", "abbbaaababanabbbaaababamm" }, { MA, 0, "a(a(\\1*)a|(b)b+){0}a", "aa" }, { MA, 0, "((?:a|)*){0}a", "a" }, /* Combining ? + * operators */ { MUA, 0, "((bm)+)?\?(?:a)*(bm)+n|((am)+?)?(?:a)+(am)*n", "bmbmabmamaaamambmaman" }, { MUA, 0, "(((ab)?cd)*ef)+g", "abcdcdefcdefefmabcdcdefcdefefgg" }, { MUA, 0, "(((ab)?\?cd)*?ef)+?g", "abcdcdefcdefefmabcdcdefcdefefgg" }, { MUA, 0, "(?:(ab)?c|(?:ab)+?d)*g", "ababcdccababddg" }, { MUA, 0, "(?:(?:ab)?\?c|(ab)+d)*?g", "ababcdccababddg" }, /* Single character iterators. */ { MUA, 0, "(a+aab)+aaaab", "aaaabcaaaabaabcaabcaaabaaaab" }, { MUA, 0, "(a*a*aab)+x", "aaaaabaabaaabmaabx" }, { MUA, 0, "(a*?(b|ab)a*?)+x", "aaaabcxbbaabaacbaaabaabax" }, { MUA, 0, "(a+(ab|ad)a+)+x", "aaabaaaadaabaaabaaaadaaax" }, { MUA, 0, "(a?(a)a?)+(aaa)", "abaaabaaaaaaaa" }, { MUA, 0, "(a?\?(a)a?\?)+(b)", "aaaacaaacaacacbaaab" }, { MUA, 0, "(a{0,4}(b))+d", "aaaaaabaabcaaaaabaaaaabd" }, { MUA, 0, "(a{0,4}?[^b])+d+(a{0,4}[^b])d+", "aaaaadaaaacaadddaaddd" }, { MUA, 0, "(ba{2})+c", "baabaaabacbaabaac" }, { MUA, 0, "(a*+bc++)+", "aaabbcaaabcccab" }, { MUA, 0, "(a?+[^b])+", "babaacacb" }, { MUA, 0, "(a{0,3}+b)(a{0,3}+b)(a{0,3}+)[^c]", "abaabaaacbaabaaaac" }, { CMUA, 0, "([a-c]+[d-f]+?)+?g", "aBdacdehAbDaFgA" }, { CMUA, 0, "[c-f]+k", "DemmFke" }, { MUA, 0, "([DGH]{0,4}M)+", "GGDGHDGMMHMDHHGHM" }, { MUA, 0, "([a-c]{4,}s)+", "abasabbasbbaabsbba" }, { CMUA, 0, "[ace]{3,7}", "AcbDAcEEcEd" }, { CMUA, 0, "[ace]{3,7}?", "AcbDAcEEcEd" }, { CMUA, 0, "[ace]{3,}", "AcbDAcEEcEd" }, { CMUA, 0, "[ace]{3,}?", "AcbDAcEEcEd" }, { MUA, 0, "[ckl]{2,}?g", "cdkkmlglglkcg" }, { CMUA, 0, "[ace]{5}?", "AcCebDAcEEcEd" }, { MUA, 0, "([AbC]{3,5}?d)+", "BACaAbbAEAACCbdCCbdCCAAbb" }, { MUA, 0, "([^ab]{0,}s){2}", "abaabcdsABamsDDs" }, { MUA, 0, "\\b\\w+\\B", "x,a_cd" }, { MUAP, 0, "\\b[^\xc2\xa1]+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, { CMUA, 0, "[^b]+(a*)([^c]?d{3})", "aaaaddd" }, { CMUAP, 0, "\xe1\xbd\xb8{2}", "\xe1\xbf\xb8#\xe1\xbf\xb8\xe1\xbd\xb8" }, { CMUA, 0, "[^\xf0\x90\x90\x80]{2,4}@", "\xf0\x90\x90\xa8\xf0\x90\x90\x80###\xf0\x90\x90\x80@@@" }, { CMUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, { MUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, { MUA, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" }, /* Basic character sets. */ { MUA, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " }, { MUA, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" }, { MUA, 0, "\\((\\d)+\\)\\D", "a() (83 (8)2 (9)ab" }, { MUA, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" }, { MUA, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" }, { MUA, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" }, /* Unicode properties. */ { MUAP, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" }, { MUAP, 0 | F_PROPERTY, "[\xc3\x81\\p{Ll}]", "A_\xc3\x89\xc3\xa1" }, { MUAP, 0, "[\\Wd-h_x-z]+", "a\xc2\xa1#_yhzdxi" }, { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}]", "abc" }, { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}]", "abc" }, { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}\xc3\xa1-\xc3\xa8]", "abc" }, { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}\xc3\xa1-\xc3\xa8]", "abc" }, { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, { MUAP, 0 | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, { MUAP, 0 | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, { MUAP, 0, "[b-\xc3\xa9\\s]", "a\xc\xe6\x92\xad" }, { CMUAP, 0, "[\xc2\x85-\xc2\x89\xc3\x89]", "\xc2\x84\xc3\xa9" }, { MUAP, 0, "[^b-d^&\\s]{3,}", "db^ !a\xe2\x80\xa8_ae" }, { MUAP, 0 | F_PROPERTY, "[^\\S\\P{Any}][\\sN]{1,3}[\\P{N}]{4}", "\xe2\x80\xaa\xa N\x9\xc3\xa9_0" }, { MUA, 0 | F_PROPERTY, "[^\\P{L}\x9!D-F\xa]{2,3}", "\x9,.DF\xa.CG\xc3\x81" }, { CMUAP, 0, "[\xc3\xa1-\xc3\xa9_\xe2\x80\xa0-\xe2\x80\xaf]{1,5}[^\xe2\x80\xa0-\xe2\x80\xaf]", "\xc2\xa1\xc3\x89\xc3\x89\xe2\x80\xaf_\xe2\x80\xa0" }, { MUAP, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" }, { MUAP, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" }, { PCRE_UCP, 0, "[a-b\\s]{2,5}[^a]", "AB baaa" }, /* Possible empty brackets. */ { MUA, 0, "(?:|ab||bc|a)+d", "abcxabcabd" }, { MUA, 0, "(|ab||bc|a)+d", "abcxabcabd" }, { MUA, 0, "(?:|ab||bc|a)*d", "abcxabcabd" }, { MUA, 0, "(|ab||bc|a)*d", "abcxabcabd" }, { MUA, 0, "(?:|ab||bc|a)+?d", "abcxabcabd" }, { MUA, 0, "(|ab||bc|a)+?d", "abcxabcabd" }, { MUA, 0, "(?:|ab||bc|a)*?d", "abcxabcabd" }, { MUA, 0, "(|ab||bc|a)*?d", "abcxabcabd" }, { MUA, 0, "(((a)*?|(?:ba)+)+?|(?:|c|ca)*)*m", "abaacaccabacabalabaacaccabacabamm" }, { MUA, 0, "(?:((?:a)*|(ba)+?)+|(|c|ca)*?)*?m", "abaacaccabacabalabaacaccabacabamm" }, /* Start offset. */ { MUA, 3, "(\\d|(?:\\w)*\\w)+", "0ac01Hb" }, { MUA, 4 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, { MUA, 2 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, { MUA, 1, "(\\w\\W\\w)+", "ab#d" }, /* Newline. */ { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, { PCRE_MULTILINE | PCRE_NEWLINE_CR, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{1,3}[^#]", "\r\n##...." }, /* Any character except newline or any newline. */ { PCRE_NEWLINE_CRLF, 0, ".", "\r" }, { PCRE_NEWLINE_CRLF | PCRE_UTF8, 0, ".(.).", "a\xc3\xa1\r\n\n\r\r" }, { PCRE_NEWLINE_ANYCRLF, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, "(.).", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa9$de" }, { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0 | F_NOMATCH, ".(.).", "\xe2\x80\xa8\nb\r" }, { PCRE_NEWLINE_ANY, 0, "(.)(.)", "#\x85#\r#\n#\r\n#\x84" }, { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, "(.+)#", "#\rMn\xc2\x85#\n###" }, { PCRE_BSR_ANYCRLF, 0, "\\R", "\r" }, { PCRE_BSR_ANYCRLF, 0, "\\R", "\x85#\r\n#" }, { PCRE_BSR_UNICODE | PCRE_UTF8, 0, "\\R", "ab\xe2\x80\xa8#c" }, { PCRE_BSR_UNICODE | PCRE_UTF8, 0, "\\R", "ab\r\nc" }, { PCRE_NEWLINE_CRLF | PCRE_BSR_UNICODE | PCRE_UTF8, 0, "(\\R.)+", "\xc2\x85\r\n#\xe2\x80\xa8\n\r\n\r" }, { MUA, 0 | F_NOMATCH, "\\R+", "ab" }, { MUA, 0, "\\R+", "ab\r\n\r" }, { MUA, 0, "\\R*", "ab\r\n\r" }, { MUA, 0, "\\R*", "\r\n\r" }, { MUA, 0, "\\R{2,4}", "\r\nab\r\r" }, { MUA, 0, "\\R{2,4}", "\r\nab\n\n\n\r\r\r" }, { MUA, 0, "\\R{2,}", "\r\nab\n\n\n\r\r\r" }, { MUA, 0, "\\R{0,3}", "\r\n\r\n\r\n\r\n\r\n" }, { MUA, 0 | F_NOMATCH, "\\R+\\R\\R", "\r\n\r\n" }, { MUA, 0, "\\R+\\R\\R", "\r\r\r" }, { MUA, 0, "\\R*\\R\\R", "\n\r" }, { MUA, 0 | F_NOMATCH, "\\R{2,4}\\R\\R", "\r\r\r" }, { MUA, 0, "\\R{2,4}\\R\\R", "\r\r\r\r" }, /* Atomic groups (no fallback from "next" direction). */ { MUA, 0 | F_NOMATCH, "(?>ab)ab", "bab" }, { MUA, 0 | F_NOMATCH, "(?>(ab))ab", "bab" }, { MUA, 0, "(?>ab)+abc(?>de)*def(?>gh)?ghe(?>ij)+?k(?>lm)*?n(?>op)?\?op", "bababcdedefgheijijklmlmnop" }, { MUA, 0, "(?>a(b)+a|(ab)?\?(b))an", "abban" }, { MUA, 0, "(?>ab+a|(?:ab)?\?b)an", "abban" }, { MUA, 0, "((?>ab|ad|)*?)(?>|c)*abad", "abababcababad" }, { MUA, 0, "(?>(aa|b|)*+(?>(##)|###)*d|(aa)(?>(baa)?)m)", "aabaa#####da" }, { MUA, 0, "((?>a|)+?)b", "aaacaaab" }, { MUA, 0, "(?>x|)*$", "aaa" }, { MUA, 0, "(?>(x)|)*$", "aaa" }, { MUA, 0, "(?>x|())*$", "aaa" }, { MUA, 0, "((?>[cxy]a|[a-d])*?)b", "aaa+ aaab" }, { MUA, 0, "((?>[cxy](a)|[a-d])*?)b", "aaa+ aaab" }, { MUA, 0, "(?>((?>(a+))))bab|(?>((?>(a+))))bb", "aaaabaaabaabab" }, { MUA, 0, "(?>(?>a+))bab|(?>(?>a+))bb", "aaaabaaabaabab" }, { MUA, 0, "(?>(a)c|(?>(c)|(a))a)b*?bab", "aaaabaaabaabab" }, { MUA, 0, "(?>ac|(?>c|a)a)b*?bab", "aaaabaaabaabab" }, { MUA, 0, "(?>(b)b|(a))*b(?>(c)|d)?x", "ababcaaabdbx" }, { MUA, 0, "(?>bb|a)*b(?>c|d)?x", "ababcaaabdbx" }, { MUA, 0, "(?>(bb)|a)*b(?>c|(d))?x", "ababcaaabdbx" }, { MUA, 0, "(?>(a))*?(?>(a))+?(?>(a))??x", "aaaaaacccaaaaabax" }, { MUA, 0, "(?>a)*?(?>a)+?(?>a)??x", "aaaaaacccaaaaabax" }, { MUA, 0, "(?>(a)|)*?(?>(a)|)+?(?>(a)|)??x", "aaaaaacccaaaaabax" }, { MUA, 0, "(?>a|)*?(?>a|)+?(?>a|)??x", "aaaaaacccaaaaabax" }, { MUA, 0, "(?>a(?>(a{0,2}))*?b|aac)+b", "aaaaaaacaaaabaaaaacaaaabaacaaabb" }, { CMA, 0, "(?>((?>a{32}|b+|(a*))?(?>c+|d*)?\?)+e)+?f", "aaccebbdde bbdaaaccebbdee bbdaaaccebbdeef" }, { MUA, 0, "(?>(?:(?>aa|a||x)+?b|(?>aa|a||(x))+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, { MUA, 0, "(?>(?:(?>aa|a||(x))+?b|(?>aa|a||x)+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, { MUA, 0 | F_NOMATCH | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d" }, { MUA, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d#\xcc\x8d\xcc\x8d" }, { MUA, 0 | F_PROPERTY, "\\X+..", "\xcc\x8d#\xcc\x8d#\xcc\x8d\xcc\x8d" }, { MUA, 0 | F_PROPERTY, "\\X{2,4}", "abcdef" }, { MUA, 0 | F_PROPERTY, "\\X{2,4}?", "abcdef" }, { MUA, 0 | F_NOMATCH | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d##" }, { MUA, 0 | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d#\xcc\x8d##" }, { MUA, 0, "(c(ab)?+ab)+", "cabcababcab" }, { MUA, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" }, /* Possessive quantifiers. */ { MUA, 0, "(?:a|b)++m", "mababbaaxababbaam" }, { MUA, 0, "(?:a|b)*+m", "mababbaaxababbaam" }, { MUA, 0, "(?:a|b)*+m", "ababbaaxababbaam" }, { MUA, 0, "(a|b)++m", "mababbaaxababbaam" }, { MUA, 0, "(a|b)*+m", "mababbaaxababbaam" }, { MUA, 0, "(a|b)*+m", "ababbaaxababbaam" }, { MUA, 0, "(a|b(*ACCEPT))++m", "maaxab" }, { MUA, 0, "(?:b*)++m", "bxbbxbbbxm" }, { MUA, 0, "(?:b*)++m", "bxbbxbbbxbbm" }, { MUA, 0, "(?:b*)*+m", "bxbbxbbbxm" }, { MUA, 0, "(?:b*)*+m", "bxbbxbbbxbbm" }, { MUA, 0, "(b*)++m", "bxbbxbbbxm" }, { MUA, 0, "(b*)++m", "bxbbxbbbxbbm" }, { MUA, 0, "(b*)*+m", "bxbbxbbbxm" }, { MUA, 0, "(b*)*+m", "bxbbxbbbxbbm" }, { MUA, 0, "(?:a|(b))++m", "mababbaaxababbaam" }, { MUA, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" }, { MUA, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" }, { MUA, 0, "(a|(b))++m", "mababbaaxababbaam" }, { MUA, 0, "((a)|b)*+m", "mababbaaxababbaam" }, { MUA, 0, "((a)|(b))*+m", "ababbaaxababbaam" }, { MUA, 0, "(a|(b)(*ACCEPT))++m", "maaxab" }, { MUA, 0, "(?:(b*))++m", "bxbbxbbbxm" }, { MUA, 0, "(?:(b*))++m", "bxbbxbbbxbbm" }, { MUA, 0, "(?:(b*))*+m", "bxbbxbbbxm" }, { MUA, 0, "(?:(b*))*+m", "bxbbxbbbxbbm" }, { MUA, 0, "((b*))++m", "bxbbxbbbxm" }, { MUA, 0, "((b*))++m", "bxbbxbbbxbbm" }, { MUA, 0, "((b*))*+m", "bxbbxbbbxm" }, { MUA, 0, "((b*))*+m", "bxbbxbbbxbbm" }, { MUA, 0 | F_NOMATCH, "(?>(b{2,4}))(?:(?:(aa|c))++m|(?:(aa|c))+n)", "bbaacaaccaaaacxbbbmbn" }, { MUA, 0, "((?:b)++a)+(cd)*+m", "bbababbacdcdnbbababbacdcdm" }, { MUA, 0, "((?:(b))++a)+((c)d)*+m", "bbababbacdcdnbbababbacdcdm" }, { MUA, 0, "(?:(?:(?:ab)*+k)++(?:n(?:cd)++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, { MUA, 0, "(?:((ab)*+(k))++(n(?:c(d))++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, /* Back references. */ { MUA, 0, "(aa|bb)(\\1*)(ll|)(\\3*)bbbbbbc", "aaaaaabbbbbbbbc" }, { CMUA, 0, "(aa|bb)(\\1+)(ll|)(\\3+)bbbbbbc", "bBbbBbCbBbbbBbbcbbBbbbBBbbC" }, { CMA, 0, "(a{2,4})\\1", "AaAaaAaA" }, { MUA, 0, "(aa|bb)(\\1?)aa(\\1?)(ll|)(\\4+)bbc", "aaaaaaaabbaabbbbaabbbbc" }, { MUA, 0, "(aa|bb)(\\1{0,5})(ll|)(\\3{0,5})cc", "bbxxbbbbxxaaaaaaaaaaaaaaaacc" }, { MUA, 0, "(aa|bb)(\\1{3,5})(ll|)(\\3{3,5})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, { MUA, 0, "(aa|bb)(\\1{3,})(ll|)(\\3{3,})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, { MUA, 0, "(\\w+)b(\\1+)c", "GabGaGaDbGaDGaDc" }, { MUA, 0, "(?:(aa)|b)\\1?b", "bb" }, { CMUA, 0, "(aa|bb)(\\1*?)aa(\\1+?)", "bBBbaaAAaaAAaa" }, { MUA, 0, "(aa|bb)(\\1*?)(dd|)cc(\\3+?)", "aaaaaccdd" }, { CMUA, 0, "(?:(aa|bb)(\\1?\?)cc){2}(\\1?\?)", "aAaABBbbAAaAcCaAcCaA" }, { MUA, 0, "(?:(aa|bb)(\\1{3,5}?)){2}(dd|)(\\3{3,5}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, { CMA, 0, "(?:(aa|bb)(\\1{3,}?)){2}(dd|)(\\3{3,}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, { MUA, 0, "(?:(aa|bb)(\\1{0,3}?)){2}(dd|)(\\3{0,3}?)b(\\1{0,3}?)(\\1{0,3})", "aaaaaaaaaaaaaaabaaaaa" }, { MUA, 0, "(a(?:\\1|)a){3}b", "aaaaaaaaaaab" }, { MA, 0, "(a?)b(\\1\\1*\\1+\\1?\\1*?\\1+?\\1??\\1*+\\1++\\1?+\\1{4}\\1{3,5}\\1{4,}\\1{0,5}\\1{3,5}?\\1{4,}?\\1{0,5}?\\1{3,5}+\\1{4,}+\\1{0,5}+#){2}d", "bb#b##d" }, { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{0,2}", "wwwww." }, { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwww" }, { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwwww" }, { PCRE_UCP, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, { CMUAP, 0, "(\xf0\x90\x90\x80)\\1", "\xf0\x90\x90\xa8\xf0\x90\x90\xa8" }, /* Assertions. */ { MUA, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" }, { MUA, 0, "(?=((\\w+)b){3}|ab)", "dbbbb ab" }, { MUA, 0, "(?!ab|bc|cd)[a-z]{2}", "Xabcdef" }, { MUA, 0, "(?<=aaa|aa|a)a", "aaa" }, { MUA, 2, "(?<=aaa|aa|a)a", "aaa" }, { MA, 0, "(?<=aaa|aa|a)a", "aaa" }, { MA, 2, "(?<=aaa|aa|a)a", "aaa" }, { MUA, 0, "(\\d{2})(?!\\w+c|(((\\w?)m){2}n)+|\\1)", "x5656" }, { MUA, 0, "((?=((\\d{2,6}\\w){2,}))\\w{5,20}K){2,}", "567v09708K12l00M00 567v09708K12l00M00K45K" }, { MUA, 0, "(?=(?:(?=\\S+a)\\w*(b)){3})\\w+\\d", "bba bbab nbbkba nbbkba0kl" }, { MUA, 0, "(?>a(?>(b+))a(?=(..)))*?k", "acabbcabbaabacabaabbakk" }, { MUA, 0, "((?(?=(a))a)+k)", "bbak" }, { MUA, 0, "((?(?=a)a)+k)", "bbak" }, { MUA, 0 | F_NOMATCH, "(?=(?>(a))m)amk", "a k" }, { MUA, 0 | F_NOMATCH, "(?!(?>(a))m)amk", "a k" }, { MUA, 0 | F_NOMATCH, "(?>(?=(a))am)amk", "a k" }, { MUA, 0, "(?=(?>a|(?=(?>(b+))a|c)[a-c]+)*?m)[a-cm]+k", "aaam bbam baaambaam abbabba baaambaamk" }, { MUA, 0, "(?> ?\?\\b(?(?=\\w{1,4}(a))m)\\w{0,8}bc){2,}?", "bca ssbc mabd ssbc mabc" }, { MUA, 0, "(?:(?=ab)?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, { MUA, 0, "(?:(?=a(b))?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, { MUA, 0, "(?:(?=.(.))??\\1.)+m", "aabbbcbacccanaabbbcbacccam" }, { MUA, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" }, { MUA, 0, "((?!a)?(?!([^a]))?)+$", "acbab" }, { MUA, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" }, /* Not empty, ACCEPT, FAIL */ { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" }, { MUA | PCRE_NOTEMPTY, 0, "a*", "bcaad" }, { MUA | PCRE_NOTEMPTY, 0, "a*?", "bcaad" }, { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a*", "bcaad" }, { MUA, 0, "a(*ACCEPT)b", "ab" }, { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a*(*ACCEPT)b", "bcx" }, { MUA | PCRE_NOTEMPTY, 0, "a*(*ACCEPT)b", "bcaad" }, { MUA | PCRE_NOTEMPTY, 0, "a*?(*ACCEPT)b", "bcaad" }, { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "(?:z|a*(*ACCEPT)b)", "bcx" }, { MUA | PCRE_NOTEMPTY, 0, "(?:z|a*(*ACCEPT)b)", "bcaad" }, { MUA | PCRE_NOTEMPTY, 0, "(?:z|a*?(*ACCEPT)b)", "bcaad" }, { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a*(*ACCEPT)b", "bcx" }, { MUA | PCRE_NOTEMPTY_ATSTART, 0 | F_NOMATCH, "a*(*ACCEPT)b", "" }, { MUA, 0, "((a(*ACCEPT)b))", "ab" }, { MUA, 0, "(a(*FAIL)a|a)", "aaa" }, { MUA, 0, "(?=ab(*ACCEPT)b)a", "ab" }, { MUA, 0, "(?=(?:x|ab(*ACCEPT)b))", "ab" }, { MUA, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" }, { MUA | PCRE_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" }, /* Conditional blocks. */ { MUA, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?!(b))a|b)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?=a)a|b)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?!b)a|b)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?=(a))a*|b*)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?!(b))a*|b*)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, { MUA, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, { MUA, 0 | F_DIFF, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, { MUA, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, { MUA, 0, "(?(?=a)a*|b*)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?!b)a*|b*)+k", "ababbalbbadabak" }, { MUA, 0, "(?(?=a)ab)", "a" }, { MUA, 0, "(?(?a)?(?Pb)?(?(Name)c|d)*l", "bc ddd abccabccl" }, { MUA, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" }, { MUA, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" }, /* Set start of match. */ { MUA, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" }, { MUA, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" }, { MUA, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" }, { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a\\K(*ACCEPT)b", "aa" }, { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a\\K(*ACCEPT)b", "aa" }, /* First line. */ { MUA | PCRE_FIRSTLINE, 0 | F_PROPERTY, "\\p{Any}a", "bb\naaa" }, { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}a", "bb\r\naaa" }, { MUA | PCRE_FIRSTLINE, 0, "(?<=a)", "a" }, { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "[^a][^b]", "ab" }, { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "a", "\na" }, { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "[abc]", "\na" }, { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^a", "\na" }, { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^(?<=\n)", "\na" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "#", "\xc2\x85#" }, { PCRE_MULTILINE | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "#", "\x85#" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^#", "\xe2\x80\xa8#" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_PROPERTY, "\\p{Any}", "\r\na" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0, ".", "\r" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0, "a", "\ra" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_NOMATCH, "ba", "bbb\r\nba" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" }, { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 1, ".", "\r\n" }, /* Recurse. */ { MUA, 0, "(a)(?1)", "aa" }, { MUA, 0, "((a))(?1)", "aa" }, { MUA, 0, "(b|a)(?1)", "aa" }, { MUA, 0, "(b|(a))(?1)", "aa" }, { MUA, 0 | F_NOMATCH, "((a)(b)(?:a*))(?1)", "aba" }, { MUA, 0, "((a)(b)(?:a*))(?1)", "abab" }, { MUA, 0, "((a+)c(?2))b(?1)", "aacaabaca" }, { MUA, 0, "((?2)b|(a)){2}(?1)", "aabab" }, { MUA, 0, "(?1)(a)*+(?2)(b(?1))", "aababa" }, { MUA, 0, "(?1)(((a(*ACCEPT)))b)", "axaa" }, { MUA, 0, "(?1)(?(DEFINE) (((ac(*ACCEPT)))b) )", "akaac" }, { MUA, 0, "(a+)b(?1)b\\1", "abaaabaaaaa" }, { MUA, 0 | F_NOMATCH, "(?(DEFINE)(aa|a))(?1)ab", "aab" }, { MUA, 0, "(?(DEFINE)(a\\Kb))(?1)+ababc", "abababxabababc" }, { MUA, 0, "(a\\Kb)(?1)+ababc", "abababxababababc" }, { MUA, 0 | F_NOMATCH, "(a\\Kb)(?1)+ababc", "abababxababababxc" }, { MUA, 0, "b|<(?R)*>", "<" }, { MUA, 0, "(a\\K){0}(?:(?1)b|ac)", "ac" }, { MUA, 0, "(?(DEFINE)(a(?2)|b)(b(?1)|(a)))(?:(?1)|(?2))m", "ababababnababababaam" }, { MUA, 0, "(a)((?(R)a|b))(?2)", "aabbabaa" }, { MUA, 0, "(a)((?(R2)a|b))(?2)", "aabbabaa" }, { MUA, 0, "(a)((?(R1)a|b))(?2)", "ababba" }, { MUA, 0, "(?(R0)aa|bb(?R))", "abba aabb bbaa" }, { MUA, 0, "((?(R)(?:aaaa|a)|(?:(aaaa)|(a)))+)(?1)$", "aaaaaaaaaa aaaa" }, { MUA, 0, "(?Pa(?(R&Name)a|b))(?1)", "aab abb abaa" }, /* 16 bit specific tests. */ { CMA, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" }, { CMA, 0 | F_FORCECONV, "\xe1\xbd\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, { CMA, 0 | F_FORCECONV, "[\xc3\xa1]", "\xc3\x81\xc3\xa1" }, { CMA, 0 | F_FORCECONV, "[\xe1\xbd\xb8]", "\xe1\xbf\xb8\xe1\xbd\xb8" }, { CMA, 0 | F_FORCECONV, "[a-\xed\xb0\x80]", "A" }, { CMA, 0 | F_NO8 | F_FORCECONV, "[a-\\x{dc00}]", "B" }, { CMA, 0 | F_NO8 | F_NOMATCH | F_FORCECONV, "[b-\\x{dc00}]", "a" }, { CMA, 0 | F_NO8 | F_FORCECONV, "\xed\xa0\x80\\x{d800}\xed\xb0\x80\\x{dc00}", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80" }, { CMA, 0 | F_NO8 | F_FORCECONV, "[\xed\xa0\x80\\x{d800}]{1,2}?[\xed\xb0\x80\\x{dc00}]{1,2}?#", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80#" }, { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80\xed\xb0\x80#]{0,3}(?<=\xed\xb0\x80.)", "\xed\xa0\x80#\xed\xa0\x80##\xed\xb0\x80\xed\xa0\x80" }, { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\x9f\xbf\xed\xa0\x83" }, { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\xb4\x80\xed\xb3\xb0" }, { CMA, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\x9f\xbf\xed\xa0\x83" }, { CMA, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\xb4\x80\xed\xb3\xb0" }, { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xef\xbf\xbf]+[\x1-\xed\xb0\x80]+#", "\xed\xa0\x85\xc3\x81\xed\xa0\x85\xef\xbf\xb0\xc2\x85\xed\xa9\x89#" }, { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80][\xed\xb0\x80]{2,}", "\xed\xa0\x80\xed\xb0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80\xed\xb0\x80" }, { MA, 0 | F_FORCECONV, "[^\xed\xb0\x80]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, { MA, 0 | F_NO8 | F_FORCECONV, "[^\\x{dc00}]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, { CMA, 0 | F_FORCECONV, ".\\B.", "\xed\xa0\x80\xed\xb0\x80" }, { CMA, 0 | F_FORCECONV, "\\D+(?:\\d+|.)\\S+(?:\\s+|.)\\W+(?:\\w+|.)\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80" }, { CMA, 0 | F_FORCECONV, "\\d*\\s*\\w*\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80" }, { CMA, 0 | F_FORCECONV | F_NOMATCH, "\\d*?\\D*?\\s*?\\S*?\\w*?\\W*?##", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80#" }, { CMA | PCRE_EXTENDED, 0 | F_FORCECONV, "\xed\xa0\x80 \xed\xb0\x80 !", "\xed\xa0\x80\xed\xb0\x80!" }, { CMA, 0 | F_FORCECONV, "\xed\xa0\x80+#[^#]+\xed\xa0\x80", "\xed\xa0\x80#a\xed\xa0\x80" }, { CMA, 0 | F_FORCECONV, "(\xed\xa0\x80+)#\\1", "\xed\xa0\x80\xed\xa0\x80#\xed\xa0\x80\xed\xa0\x80" }, { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0 | F_NO8 | F_FORCECONV, "^-", "a--\xe2\x80\xa8--" }, { PCRE_BSR_UNICODE, 0 | F_NO8 | F_FORCECONV, "\\R", "ab\xe2\x80\xa8" }, { 0, 0 | F_NO8 | F_FORCECONV, "\\v", "ab\xe2\x80\xa9" }, { 0, 0 | F_NO8 | F_FORCECONV, "\\h", "ab\xe1\xa0\x8e" }, { 0, 0 | F_NO8 | F_FORCECONV, "\\v+?\\V+?#", "\xe2\x80\xa9\xe2\x80\xa9\xef\xbf\xbf\xef\xbf\xbf#" }, { 0, 0 | F_NO8 | F_FORCECONV, "\\h+?\\H+?#", "\xe1\xa0\x8e\xe1\xa0\x8e\xef\xbf\xbf\xef\xbf\xbf#" }, /* Partial matching. */ { MUA | PCRE_PARTIAL_SOFT, 0, "ab", "a" }, { MUA | PCRE_PARTIAL_SOFT, 0, "ab|a", "a" }, { MUA | PCRE_PARTIAL_HARD, 0, "ab|a", "a" }, { MUA | PCRE_PARTIAL_SOFT, 0, "\\b#", "a" }, { MUA | PCRE_PARTIAL_SOFT, 0, "(?<=a)b", "a" }, { MUA | PCRE_PARTIAL_SOFT, 0, "abc|(?<=xxa)bc", "xxab" }, { MUA | PCRE_PARTIAL_SOFT, 0, "a\\B", "a" }, { MUA | PCRE_PARTIAL_HARD, 0, "a\\b", "a" }, /* (*MARK) verb. */ { MUA, 0, "a(*MARK:aa)a", "ababaa" }, { MUA, 0 | F_NOMATCH, "a(*:aa)a", "abab" }, { MUA, 0, "a(*:aa)(b(*:bb)b|bc)", "abc" }, { MUA, 0 | F_NOMATCH, "a(*:1)x|b(*:2)y", "abc" }, { MUA, 0, "(?>a(*:aa))b|ac", "ac" }, { MUA, 0, "(?(DEFINE)(a(*:aa)))(?1)", "a" }, { MUA, 0 | F_NOMATCH, "(?(DEFINE)((a)(*:aa)))(?1)b", "aa" }, { MUA, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" }, { MUA, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, { MUA, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" }, { MUA, 0 | F_NOMATCH, "(a(*:aa)){0}(?:b(?1)b)+", "ba" }, { MUA, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, { MUA, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" }, { MUA, 0 | F_NOMATCH, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" }, /* (*COMMIT) verb. */ { MUA, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" }, { MUA, 0, "aa(*COMMIT)b", "xaxaab" }, { MUA, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" }, { MUA, 0, "(?=a(*COMMIT)b|ac)ac|(*:m)(a)c", "ac" }, { MUA, 0, "(?!a(*COMMIT)(*:msg)b)a(c)|cd", "acd" }, /* Deep recursion. */ { MUA, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " }, { MUA, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " }, { MUA, 0, "((a?)+)+b", "aaaaaaaaaaaa b" }, /* Deep recursion: Stack limit reached. */ { MA, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" }, { MA, 0 | F_NOMATCH, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, { MA, 0 | F_NOMATCH, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, { MA, 0 | F_NOMATCH, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, { MA, 0 | F_NOMATCH, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, { 0, 0, NULL, NULL } }; static const unsigned char *tables(int mode) { /* The purpose of this function to allow valgrind for reporting invalid reads and writes. */ static unsigned char *tables_copy; const char *errorptr; int erroroffset; unsigned char *default_tables; #ifdef SUPPORT_PCRE8 pcre *regex; char null_str[1] = { 0 }; #else pcre16 *regex; PCRE_UCHAR16 null_str[1] = { 0 }; #endif if (mode) { if (tables_copy) free(tables_copy); tables_copy = NULL; return NULL; } if (tables_copy) return tables_copy; default_tables = NULL; #ifdef SUPPORT_PCRE8 regex = pcre_compile(null_str, 0, &errorptr, &erroroffset, NULL); if (regex) { pcre_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables); pcre_free(regex); } #else regex = pcre16_compile(null_str, 0, &errorptr, &erroroffset, NULL); if (regex) { pcre16_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables); pcre16_free(regex); } #endif /* Shouldn't ever happen. */ if (!default_tables) return NULL; /* Unfortunately this value cannot get from pcre_fullinfo. Since this is a test program, this is acceptable at the moment. */ tables_copy = (unsigned char *)malloc(1088); if (!tables_copy) return NULL; memcpy(tables_copy, default_tables, 1088); return tables_copy; } #ifdef SUPPORT_PCRE8 static pcre_jit_stack* callback8(void *arg) { return (pcre_jit_stack *)arg; } #endif #ifdef SUPPORT_PCRE16 static pcre16_jit_stack* callback16(void *arg) { return (pcre16_jit_stack *)arg; } #endif #ifdef SUPPORT_PCRE8 static void setstack8(pcre_extra *extra) { static pcre_jit_stack *stack; if (!extra) { if (stack) pcre_jit_stack_free(stack); stack = NULL; return; } if (!stack) stack = pcre_jit_stack_alloc(1, 1024 * 1024); /* Extra can be NULL. */ pcre_assign_jit_stack(extra, callback8, stack); } #endif /* SUPPORT_PCRE8 */ #ifdef SUPPORT_PCRE16 static void setstack16(pcre16_extra *extra) { static pcre16_jit_stack *stack; if (!extra) { if (stack) pcre16_jit_stack_free(stack); stack = NULL; return; } if (!stack) stack = pcre16_jit_stack_alloc(1, 1024 * 1024); /* Extra can be NULL. */ pcre16_assign_jit_stack(extra, callback16, stack); } #endif /* SUPPORT_PCRE8 */ #ifdef SUPPORT_PCRE16 static int convert_utf8_to_utf16(const char *input, PCRE_UCHAR16 *output, int *offsetmap, int max_length) { unsigned char *iptr = (unsigned char*)input; unsigned short *optr = (unsigned short *)output; unsigned int c; if (max_length == 0) return 0; while (*iptr && max_length > 1) { c = 0; if (offsetmap) *offsetmap++ = (int)(iptr - (unsigned char*)input); if (!(*iptr & 0x80)) c = *iptr++; else if (!(*iptr & 0x20)) { c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); iptr += 2; } else if (!(*iptr & 0x10)) { c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f); iptr += 3; } else if (!(*iptr & 0x08)) { c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f); iptr += 4; } if (c < 65536) { *optr++ = c; max_length--; } else if (max_length <= 2) { *optr = '\0'; return (int)(optr - (unsigned short *)output); } else { c -= 0x10000; *optr++ = 0xd800 | ((c >> 10) & 0x3ff); *optr++ = 0xdc00 | (c & 0x3ff); max_length -= 2; if (offsetmap) offsetmap++; } } if (offsetmap) *offsetmap = (int)(iptr - (unsigned char*)input); *optr = '\0'; return (int)(optr - (unsigned short *)output); } static int copy_char8_to_char16(const char *input, PCRE_UCHAR16 *output, int max_length) { unsigned char *iptr = (unsigned char*)input; unsigned short *optr = (unsigned short *)output; if (max_length == 0) return 0; while (*iptr && max_length > 1) { *optr++ = *iptr++; max_length--; } *optr = '\0'; return (int)(optr - (unsigned short *)output); } #define REGTEST_MAX_LENGTH 4096 static PCRE_UCHAR16 regtest_buf[REGTEST_MAX_LENGTH]; static int regtest_offsetmap[REGTEST_MAX_LENGTH]; #endif /* SUPPORT_PCRE16 */ static int check_ascii(const char *input) { const unsigned char *ptr = (unsigned char *)input; while (*ptr) { if (*ptr > 127) return 0; ptr++; } return 1; } static int regression_tests(void) { struct regression_test_case *current = regression_test_cases; const char *error; char *cpu_info; int i, err_offs; int is_successful, is_ascii_pattern, is_ascii_input; int total = 0; int successful = 0; int successful_row = 0; int counter = 0; int study_mode; #ifdef SUPPORT_PCRE8 pcre *re8; pcre_extra *extra8; pcre_extra dummy_extra8; int ovector8_1[32]; int ovector8_2[32]; int return_value8_1, return_value8_2; unsigned char *mark8_1, *mark8_2; int utf8 = 0, ucp8 = 0; int disabled_flags8 = 0; #endif #ifdef SUPPORT_PCRE16 pcre16 *re16; pcre16_extra *extra16; pcre16_extra dummy_extra16; int ovector16_1[32]; int ovector16_2[32]; int return_value16_1, return_value16_2; PCRE_UCHAR16 *mark16_1, *mark16_2; int utf16 = 0, ucp16 = 0; int disabled_flags16 = 0; int length16; #endif /* This test compares the behaviour of interpreter and JIT. Although disabling utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is still considered successful from pcre_jit_test point of view. */ #ifdef SUPPORT_PCRE8 pcre_config(PCRE_CONFIG_JITTARGET, &cpu_info); #else pcre16_config(PCRE_CONFIG_JITTARGET, &cpu_info); #endif printf("Running JIT regression tests\n"); printf(" target CPU of SLJIT compiler: %s\n", cpu_info); #ifdef SUPPORT_PCRE8 pcre_config(PCRE_CONFIG_UTF8, &utf8); pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp8); if (!utf8) disabled_flags8 |= PCRE_UTF8; if (!ucp8) disabled_flags8 |= PCRE_UCP; printf(" in 8 bit mode with utf8 %s and ucp %s:\n", utf8 ? "enabled" : "disabled", ucp8 ? "enabled" : "disabled"); #endif #ifdef SUPPORT_PCRE16 pcre16_config(PCRE_CONFIG_UTF16, &utf16); pcre16_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp16); if (!utf16) disabled_flags16 |= PCRE_UTF8; if (!ucp16) disabled_flags16 |= PCRE_UCP; printf(" in 16 bit mode with utf16 %s and ucp %s:\n", utf16 ? "enabled" : "disabled", ucp16 ? "enabled" : "disabled"); #endif while (current->pattern) { /* printf("\nPattern: %s :\n", current->pattern); */ total++; if (current->start_offset & F_PROPERTY) { is_ascii_pattern = 0; is_ascii_input = 0; } else { is_ascii_pattern = check_ascii(current->pattern); is_ascii_input = check_ascii(current->input); } if (current->flags & PCRE_PARTIAL_SOFT) study_mode = PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE; else if (current->flags & PCRE_PARTIAL_HARD) study_mode = PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE; else study_mode = PCRE_STUDY_JIT_COMPILE; error = NULL; #ifdef SUPPORT_PCRE8 re8 = NULL; if (!(current->start_offset & F_NO8)) re8 = pcre_compile(current->pattern, current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags8), &error, &err_offs, tables(0)); extra8 = NULL; if (re8) { error = NULL; extra8 = pcre_study(re8, study_mode, &error); if (!extra8) { printf("\n8 bit: Cannot study pattern: %s\n", current->pattern); pcre_free(re8); re8 = NULL; } if (!(extra8->flags & PCRE_EXTRA_EXECUTABLE_JIT)) { printf("\n8 bit: JIT compiler does not support: %s\n", current->pattern); pcre_free_study(extra8); pcre_free(re8); re8 = NULL; } extra8->flags |= PCRE_EXTRA_MARK; } else if (((utf8 && ucp8) || is_ascii_pattern) && !(current->start_offset & F_NO8)) printf("\n8 bit: Cannot compile pattern: %s\n", current->pattern); #endif #ifdef SUPPORT_PCRE16 if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV)) convert_utf8_to_utf16(current->pattern, regtest_buf, NULL, REGTEST_MAX_LENGTH); else copy_char8_to_char16(current->pattern, regtest_buf, REGTEST_MAX_LENGTH); re16 = NULL; if (!(current->start_offset & F_NO16)) re16 = pcre16_compile(regtest_buf, current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags16), &error, &err_offs, tables(0)); extra16 = NULL; if (re16) { error = NULL; extra16 = pcre16_study(re16, study_mode, &error); if (!extra16) { printf("\n16 bit: Cannot study pattern: %s\n", current->pattern); pcre16_free(re16); re16 = NULL; } if (!(extra16->flags & PCRE_EXTRA_EXECUTABLE_JIT)) { printf("\n16 bit: JIT compiler does not support: %s\n", current->pattern); pcre16_free_study(extra16); pcre16_free(re16); re16 = NULL; } extra16->flags |= PCRE_EXTRA_MARK; } else if (((utf16 && ucp16) || is_ascii_pattern) && !(current->start_offset & F_NO16)) printf("\n16 bit: Cannot compile pattern: %s\n", current->pattern); #endif counter++; if ((counter & 0x3) != 0) { #ifdef SUPPORT_PCRE8 setstack8(NULL); #endif #ifdef SUPPORT_PCRE16 setstack16(NULL); #endif } #ifdef SUPPORT_PCRE8 return_value8_1 = -1000; return_value8_2 = -1000; for (i = 0; i < 32; ++i) ovector8_1[i] = -2; for (i = 0; i < 32; ++i) ovector8_2[i] = -2; if (re8) { mark8_1 = NULL; mark8_2 = NULL; setstack8(extra8); extra8->mark = &mark8_1; return_value8_1 = pcre_exec(re8, extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK, current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_1, 32); memset(&dummy_extra8, 0, sizeof(pcre_extra)); dummy_extra8.flags = PCRE_EXTRA_MARK; dummy_extra8.mark = &mark8_2; return_value8_2 = pcre_exec(re8, &dummy_extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK, current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_2, 32); } #endif #ifdef SUPPORT_PCRE16 return_value16_1 = -1000; return_value16_2 = -1000; for (i = 0; i < 32; ++i) ovector16_1[i] = -2; for (i = 0; i < 32; ++i) ovector16_2[i] = -2; if (re16) { mark16_1 = NULL; mark16_2 = NULL; setstack16(extra16); if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV)) length16 = convert_utf8_to_utf16(current->input, regtest_buf, regtest_offsetmap, REGTEST_MAX_LENGTH); else length16 = copy_char8_to_char16(current->input, regtest_buf, REGTEST_MAX_LENGTH); extra16->mark = &mark16_1; return_value16_1 = pcre16_exec(re16, extra16, regtest_buf, length16, current->start_offset & OFFSET_MASK, current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_1, 32); memset(&dummy_extra16, 0, sizeof(pcre16_extra)); dummy_extra16.flags = PCRE_EXTRA_MARK; dummy_extra16.mark = &mark16_2; return_value16_2 = pcre16_exec(re16, &dummy_extra16, regtest_buf, length16, current->start_offset & OFFSET_MASK, current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_2, 32); } #endif /* printf("[%d-%d|%d-%d|%d-%d]%s", return_value8_1, return_value16_1, ovector8_1[0], ovector8_1[1], ovector16_1[0], ovector16_1[1], (current->flags & PCRE_CASELESS) ? "C" : ""); */ /* If F_DIFF is set, just run the test, but do not compare the results. Segfaults can still be captured. */ is_successful = 1; if (!(current->start_offset & F_DIFF)) { #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 if (utf8 == utf16 && !(current->start_offset & F_FORCECONV)) { /* All results must be the same. */ if (return_value8_1 != return_value8_2 || return_value8_1 != return_value16_1 || return_value8_1 != return_value16_2) { printf("\n8 and 16 bit: Return value differs(%d:%d:%d:%d): [%d] '%s' @ '%s'\n", return_value8_1, return_value8_2, return_value16_1, return_value16_2, total, current->pattern, current->input); is_successful = 0; } else if (return_value8_1 >= 0 || return_value8_1 == PCRE_ERROR_PARTIAL) { if (return_value8_1 == PCRE_ERROR_PARTIAL) { return_value8_1 = 2; return_value16_1 = 2; } else { return_value8_1 *= 2; return_value16_1 *= 2; } /* Transform back the results. */ if (current->flags & PCRE_UTF8) { for (i = 0; i < return_value8_1; ++i) { if (ovector16_1[i] >= 0) ovector16_1[i] = regtest_offsetmap[ovector16_1[i]]; if (ovector16_2[i] >= 0) ovector16_2[i] = regtest_offsetmap[ovector16_2[i]]; } } for (i = 0; i < return_value8_1; ++i) if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) { printf("\n8 and 16 bit: Ovector[%d] value differs(%d:%d:%d:%d): [%d] '%s' @ '%s' \n", i, ovector8_1[i], ovector8_2[i], ovector16_1[i], ovector16_2[i], total, current->pattern, current->input); is_successful = 0; } } } else { #endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */ /* Only the 8 bit and 16 bit results must be equal. */ #ifdef SUPPORT_PCRE8 if (return_value8_1 != return_value8_2) { printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", return_value8_1, return_value8_2, total, current->pattern, current->input); is_successful = 0; } else if (return_value8_1 >= 0 || return_value8_1 == PCRE_ERROR_PARTIAL) { if (return_value8_1 == PCRE_ERROR_PARTIAL) return_value8_1 = 2; else return_value8_1 *= 2; for (i = 0; i < return_value8_1; ++i) if (ovector8_1[i] != ovector8_2[i]) { printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", i, ovector8_1[i], ovector8_2[i], total, current->pattern, current->input); is_successful = 0; } } #endif #ifdef SUPPORT_PCRE16 if (return_value16_1 != return_value16_2) { printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", return_value16_1, return_value16_2, total, current->pattern, current->input); is_successful = 0; } else if (return_value16_1 >= 0 || return_value16_1 == PCRE_ERROR_PARTIAL) { if (return_value16_1 == PCRE_ERROR_PARTIAL) return_value16_1 = 2; else return_value16_1 *= 2; for (i = 0; i < return_value16_1; ++i) if (ovector16_1[i] != ovector16_2[i]) { printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", i, ovector16_1[i], ovector16_2[i], total, current->pattern, current->input); is_successful = 0; } } #endif #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 } #endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */ } if (is_successful) { #ifdef SUPPORT_PCRE8 if (!(current->start_offset & F_NO8) && ((utf8 && ucp8) || is_ascii_input)) { if (return_value8_1 < 0 && !(current->start_offset & F_NOMATCH)) { printf("8 bit: Test should match: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); is_successful = 0; } if (return_value8_1 >= 0 && (current->start_offset & F_NOMATCH)) { printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); is_successful = 0; } } #endif #ifdef SUPPORT_PCRE16 if (!(current->start_offset & F_NO16) && ((utf16 && ucp16) || is_ascii_input)) { if (return_value16_1 < 0 && !(current->start_offset & F_NOMATCH)) { printf("16 bit: Test should match: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); is_successful = 0; } if (return_value16_1 >= 0 && (current->start_offset & F_NOMATCH)) { printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); is_successful = 0; } } #endif } if (is_successful) { #ifdef SUPPORT_PCRE8 if (mark8_1 != mark8_2) { printf("8 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); is_successful = 0; } #endif #ifdef SUPPORT_PCRE16 if (mark16_1 != mark16_2) { printf("16 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); is_successful = 0; } #endif } #ifdef SUPPORT_PCRE8 if (re8) { pcre_free_study(extra8); pcre_free(re8); } #endif #ifdef SUPPORT_PCRE16 if (re16) { pcre16_free_study(extra16); pcre16_free(re16); } #endif if (is_successful) { successful++; successful_row++; printf("."); if (successful_row >= 60) { successful_row = 0; printf("\n"); } } else successful_row = 0; fflush(stdout); current++; } tables(1); #ifdef SUPPORT_PCRE8 setstack8(NULL); #endif #ifdef SUPPORT_PCRE16 setstack16(NULL); #endif if (total == successful) { printf("\nAll JIT regression tests are successfully passed.\n"); return 0; } else { printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful); return 1; } } /* End of pcre_jit_test.c */ pcre-8.31/PrepareRelease0000755000222100022210000001652711767661427012164 00000000000000#/bin/sh # Script to prepare the files for building a PCRE release. It does some # processing of the documentation, detrails files, and creates pcre.h.generic # and config.h.generic (for use by builders who can't run ./configure). # You must run this script before runnning "make dist". If its first argument # is "doc", it stops after preparing the documentation. There are no other # arguments. The script makes use of the following files: # 132html A Perl script that converts a .1 or .3 man page into HTML. It # "knows" the relevant troff constructs that are used in the PCRE # man pages. # CheckMan A Perl script that checks man pages for typos in the mark up. # CleanTxt A Perl script that cleans up the output of "nroff -man" by # removing backspaces and other redundant text so as to produce # a readable .txt file. # Detrail A Perl script that removes trailing spaces from files. # doc/index.html.src # A file that is copied as index.html into the doc/html directory # when the HTML documentation is built. It works like this so that # doc/html can be deleted and re-created from scratch. # First, sort out the documentation. Remove pcredemo.3 first because it won't # pass the markup check (it is created below, using markup that none of the # other pages use). cd doc echo Processing documentation /bin/rm -f pcredemo.3 # Check the remaining man pages perl ../CheckMan *.1 *.3 if [ $? != 0 ] ; then exit 1; fi # Make Text form of the documentation. It needs some mangling to make it # tidy for online reading. Concatenate all the .3 stuff, but omit the # individual function pages. cat <pcre.txt ----------------------------------------------------------------------------- This file contains a concatenation of the PCRE man pages, converted to plain text format for ease of searching with a text editor, or for use on systems that do not have a man page processor. The small individual files that give synopses of each function in the library have not been included. Neither has the pcredemo program. There are separate text files for the pcregrep and pcretest commands. ----------------------------------------------------------------------------- End echo "Making pcre.txt" for file in pcre pcre16 pcrebuild pcrematching pcreapi pcrecallout pcrecompat \ pcrepattern pcresyntax pcreunicode pcrejit pcrepartial \ pcreprecompile pcreperform pcreposix pcrecpp pcresample \ pcrelimits pcrestack ; do echo " Processing $file.3" nroff -c -man $file.3 >$file.rawtxt perl ../CleanTxt <$file.rawtxt >>pcre.txt /bin/rm $file.rawtxt echo "------------------------------------------------------------------------------" >>pcre.txt if [ "$file" != "pcresample" ] ; then echo " " >>pcre.txt echo " " >>pcre.txt fi done # The three commands for file in pcretest pcregrep pcre-config ; do echo Making $file.txt nroff -c -man $file.1 >$file.rawtxt perl ../CleanTxt <$file.rawtxt >$file.txt /bin/rm $file.rawtxt done # Make pcredemo.3 from the pcredemo.c source file echo "Making pcredemo.3" perl <<"END" >pcredemo.3 open(IN, "../pcredemo.c") || die "Failed to open pcredemo.c\n"; open(OUT, ">pcredemo.3") || die "Failed to open pcredemo.3\n"; print OUT ".\\\" Start example.\n" . ".de EX\n" . ". nr mE \\\\n(.f\n" . ". nf\n" . ". nh\n" . ". ft CW\n" . "..\n" . ".\n" . ".\n" . ".\\\" End example.\n" . ".de EE\n" . ". ft \\\\n(mE\n" . ". fi\n" . ". hy \\\\n(HY\n" . "..\n" . ".\n" . ".EX\n" ; while () { s/\\/\\e/g; print OUT; } print OUT ".EE\n"; close(IN); close(OUT); END if [ $? != 0 ] ; then exit 1; fi # Make HTML form of the documentation. echo "Making HTML documentation" /bin/rm html/* cp index.html.src html/index.html for file in *.1 ; do base=`basename $file .1` echo " Making $base.html" perl ../132html -toc $base <$file >html/$base.html done # Exclude table of contents for function summaries. It seems that expr # forces an anchored regex. Also exclude them for small pages that have # only one section. for file in *.3 ; do base=`basename $file .3` toc=-toc if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi if [ "$base" = "pcresample" ] || \ [ "$base" = "pcrestack" ] || \ [ "$base" = "pcrecompat" ] || \ [ "$base" = "pcrelimits" ] || \ [ "$base" = "pcreperform" ] || \ [ "$base" = "pcreunicode" ] ; then toc="" fi echo " Making $base.html" perl ../132html $toc $base <$file >html/$base.html if [ $? != 0 ] ; then exit 1; fi done # End of documentation processing; stop if only documentation required. cd .. echo Documentation done if [ "$1" = "doc" ] ; then exit; fi # These files are detrailed; do not detrail the test data because there may be # significant trailing spaces. Do not detrail RunTest.bat, because it has CRLF # line endings and the detrail script removes all trailing white space. The # configure files are also omitted from the detrailing. We don't bother with # those pcre16_xx files that just define COMPILE_PCRE16 and then #include the # common file, because they aren't going to change. files="\ Makefile.am \ Makefile.in \ configure.ac \ README \ LICENCE \ COPYING \ AUTHORS \ NEWS \ NON-UNIX-USE \ NON-AUTOTOOLS-BUILD \ INSTALL \ 132html \ CleanTxt \ Detrail \ ChangeLog \ CMakeLists.txt \ RunGrepTest \ RunTest \ pcre-config.in \ libpcre.pc.in \ libpcre16.pc.in \ libpcreposix.pc.in \ libpcrecpp.pc.in \ config.h.in \ pcre_chartables.c.dist \ pcredemo.c \ pcregrep.c \ pcretest.c \ dftables.c \ pcreposix.c \ pcreposix.h \ pcre.h.in \ pcre_internal.h pcre_byte_order.c \ pcre_compile.c \ pcre_config.c \ pcre_dfa_exec.c \ pcre_exec.c \ pcre_fullinfo.c \ pcre_get.c \ pcre_globals.c \ pcre_jit_compile.c \ pcre_jit_test.c \ pcre_maketables.c \ pcre_newline.c \ pcre_ord2utf8.c \ pcre16_ord2utf16.c \ pcre_printint.c \ pcre_refcount.c \ pcre_string_utils.c \ pcre_study.c \ pcre_tables.c \ pcre_ucp_searchfuncs.c \ pcre_valid_utf8.c \ pcre_version.c \ pcre_xclass.c \ pcre16_utf16_utils.c \ pcre16_valid_utf16.c \ pcre_scanner.cc \ pcre_scanner.h \ pcre_scanner_unittest.cc \ pcrecpp.cc \ pcrecpp.h \ pcrecpparg.h.in \ pcrecpp_unittest.cc \ pcre_stringpiece.cc \ pcre_stringpiece.h.in \ pcre_stringpiece_unittest.cc \ perltest.pl \ ucp.h \ ucpinternal.h \ ucptable.h \ makevp.bat \ pcre.def \ libpcre.def \ libpcreposix.def" echo Detrailing perl ./Detrail $files doc/p* doc/html/* echo Doing basic configure to get default pcre.h and config.h # This is in case the caller has set aliases (as I do - PH) unset cp ls mv rm ./configure >/dev/null echo Converting pcre.h and config.h to generic forms cp -f pcre.h pcre.h.generic perl <<'END' open(IN, "config.h.generic") || die "Can't open config.h.generic: $!\n"; while () { if (/^#define\s(?!PACKAGE)(\w+)/) { print OUT "#ifndef $1\n"; print OUT; print OUT "#endif\n"; } else { print OUT; } } close IN; close OUT; END echo Done #End pcre-8.31/LICENCE0000644000222100022210000000603311676645226010311 00000000000000PCRE LICENCE ------------ PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Release 8 of PCRE is distributed under the terms of the "BSD" licence, as specified below. The documentation for PCRE, supplied in the "doc" directory, is distributed under the same terms as the software itself. The basic library functions are written in C and are freestanding. Also included in the distribution is a set of C++ wrapper functions, and a just-in-time compiler that can be used to optimize pattern matching. These are both optional features that can be omitted when the library is built. THE BASIC LIBRARY FUNCTIONS --------------------------- Written by: Philip Hazel Email local part: ph10 Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. Copyright (c) 1997-2012 University of Cambridge All rights reserved. PCRE JUST-IN-TIME COMPILATION SUPPORT ------------------------------------- Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu Copyright(c) 2010-2012 Zoltan Herczeg All rights reserved. STACK-LESS JUST-IN-TIME COMPILER -------------------------------- Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu Copyright(c) 2009-2012 Zoltan Herczeg All rights reserved. THE C++ WRAPPER FUNCTIONS ------------------------- Contributed by: Google Inc. Copyright (c) 2007-2012, Google Inc. All rights reserved. THE "BSD" LICENCE ----------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the name of Google Inc. nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. End pcre-8.31/pcre_get.c0000644000222100022210000004522111705300547011245 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains some convenience functions for extracting substrings from the subject string after a regex match has succeeded. The original idea for these functions came from Scott Wimer. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Find number for named string * *************************************************/ /* 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 stringname the name whose number is required Returns: the number of the named parentheses, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringnumber(const pcre *code, const char *stringname) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname) #endif { int rc; int entrysize; int top, bot; pcre_uchar *nametable; #ifdef COMPILE_PCRE8 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; #endif #ifdef COMPILE_PCRE16 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) return rc; if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; #endif bot = 0; while (top > bot) { int mid = (top + bot) / 2; pcre_uchar *entry = nametable + entrysize*mid; int c = STRCMP_UC_UC((pcre_uchar *)stringname, (pcre_uchar *)(entry + IMM2_SIZE)); if (c == 0) return GET2(entry, 0); if (c > 0) bot = mid + 1; else top = mid; } 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 */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringtable_entries(const pcre *code, const char *stringname, char **firstptr, char **lastptr) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname, PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr) #endif { int rc; int entrysize; int top, bot; pcre_uchar *nametable, *lastentry; #ifdef COMPILE_PCRE8 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; #endif #ifdef COMPILE_PCRE16 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) return rc; if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; #endif lastentry = nametable + entrysize * (top - 1); bot = 0; while (top > bot) { int mid = (top + bot) / 2; pcre_uchar *entry = nametable + entrysize*mid; int c = STRCMP_UC_UC((pcre_uchar *)stringname, (pcre_uchar *)(entry + IMM2_SIZE)); if (c == 0) { pcre_uchar *first = entry; pcre_uchar *last = entry; while (first > nametable) { if (STRCMP_UC_UC((pcre_uchar *)stringname, (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break; first -= entrysize; } while (last < lastentry) { if (STRCMP_UC_UC((pcre_uchar *)stringname, (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break; last += entrysize; } #ifdef COMPILE_PCRE8 *firstptr = (char *)first; *lastptr = (char *)last; #else *firstptr = (PCRE_UCHAR16 *)first; *lastptr = (PCRE_UCHAR16 *)last; #endif 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 */ #ifdef COMPILE_PCRE8 static int get_first_set(const pcre *code, const char *stringname, int *ovector) #else static int get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector) #endif { const REAL_PCRE *re = (const REAL_PCRE *)code; int entrysize; pcre_uchar *entry; #ifdef COMPILE_PCRE8 char *first, *last; #else PCRE_UCHAR16 *first, *last; #endif #ifdef COMPILE_PCRE8 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) return pcre_get_stringnumber(code, stringname); entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last); #else if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) return pcre16_get_stringnumber(code, stringname); entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last); #endif if (entrysize <= 0) return entrysize; for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize) { int n = GET2(entry, 0); if (ovector[n*2] >= 0) return n; } return GET2(entry, 0); } /************************************************* * Copy captured string to given buffer * *************************************************/ /* This function copies a single captured substring into a given buffer. Note that we use memcpy() rather than strncpy() in case there are binary zeros in the string. Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringnumber the number of the required substring buffer where to put the substring size the size of the buffer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) buffer too small PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, int size) #endif { int yield; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; if (size < yield + 1) return PCRE_ERROR_NOMEMORY; memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield)); buffer[yield] = 0; return yield; } /************************************************* * Copy named captured string to given buffer * *************************************************/ /* This function copies a single captured substring into a given buffer, identifying it by name. If the regex permits duplicate names, the first substring that is set is chosen. Arguments: code the compiled regex subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringname the name of the required substring buffer where to put the substring size the size of the buffer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) buffer too small PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int size) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_UCHAR16 *buffer, int size) #endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; #ifdef COMPILE_PCRE8 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); #else return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size); #endif } /************************************************* * Copy all captured strings to new store * *************************************************/ /* This function gets one chunk of store and builds a list of pointers and all of the captured substrings in it. A NULL pointer is put on the end of the list. Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) listptr set to point to the list of pointers Returns: if successful: 0 if not successful: PCRE_ERROR_NOMEMORY (-6) failed to get store */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 **listptr) #endif { int i; int size = sizeof(pcre_uchar *); int double_count = stringcount * 2; pcre_uchar **stringlist; pcre_uchar *p; for (i = 0; i < double_count; i += 2) size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1); stringlist = (pcre_uchar **)(PUBL(malloc))(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; #ifdef COMPILE_PCRE8 *listptr = (const char **)stringlist; #else *listptr = (PCRE_SPTR16 *)stringlist; #endif p = (pcre_uchar *)(stringlist + stringcount + 1); for (i = 0; i < double_count; i += 2) { int len = ovector[i+1] - ovector[i]; memcpy(p, subject + ovector[i], IN_UCHARS(len)); *stringlist++ = p; p += len; *p++ = 0; } *stringlist = NULL; return 0; } /************************************************* * Free store obtained by get_substring_list * *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C programs that can call its functions, but not free() or (PUBL(free))() directly. Argument: the result of a previous pcre_get_substring_list() Returns: nothing */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring_list(const char **pointer) #else PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre16_free_substring_list(PCRE_SPTR16 *pointer) #endif { (PUBL(free))((void *)pointer); } /************************************************* * Copy captured string to new store * *************************************************/ /* This function copies a single captured substring into a piece of new store Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringnumber the number of the required substring stringptr where to put a pointer to the substring Returns: if successful: the length of the string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) failed to get store PCRE_ERROR_NOSUBSTRING (-7) substring not present */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_SPTR16 *stringptr) #endif { int yield; pcre_uchar *substring; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1)); if (substring == NULL) return PCRE_ERROR_NOMEMORY; memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield)); substring[yield] = 0; #ifdef COMPILE_PCRE8 *stringptr = (const char *)substring; #else *stringptr = (PCRE_SPTR16)substring; #endif return yield; } /************************************************* * Copy named captured string to new store * *************************************************/ /* This function copies a single captured substring, identified by name, into new store. If the regex permits duplicate names, the first substring that is set is chosen. Arguments: code the compiled regex subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringname the name of the required substring stringptr where to put the pointer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) couldn't get memory PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_SPTR16 *stringptr) #endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; #ifdef COMPILE_PCRE8 return pcre_get_substring(subject, ovector, stringcount, n, stringptr); #else return pcre16_get_substring(subject, ovector, stringcount, n, stringptr); #endif } /************************************************* * Free store obtained by get_substring * *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C programs that can call its functions, but not free() or (PUBL(free))() directly. Argument: the result of a previous pcre_get_substring() Returns: nothing */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring(const char *pointer) #else PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre16_free_substring(PCRE_SPTR16 pointer) #endif { (PUBL(free))((void *)pointer); } /* End of pcre_get.c */ pcre-8.31/cmake/0000755000222100022210000000000011775533032010451 500000000000000pcre-8.31/cmake/FindPackageHandleStandardArgs.cmake0000644000222100022210000000455210744057742017153 00000000000000# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... ) # This macro is intended to be used in FindXXX.cmake modules files. # It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and # it also sets the _FOUND variable. # The package is found if all variables listed are TRUE. # Example: # # FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) # # LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and # LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. # If it is not found and REQUIRED was used, it fails with FATAL_ERROR, # independent whether QUIET was used or not. # If it is found, the location is reported using the VAR1 argument, so # here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out. # If the second argument is DEFAULT_MSG, the message in the failure case will # be "Could NOT find LibXml2", if you don't like this message you can specify # your own custom failure message there. MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 ) IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") IF (${_NAME}_FIND_REQUIRED) SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}") ELSE (${_NAME}_FIND_REQUIRED) SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}") ENDIF (${_NAME}_FIND_REQUIRED) ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") SET(_FAIL_MESSAGE "${_FAIL_MSG}") ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") STRING(TOUPPER ${_NAME} _NAME_UPPER) SET(${_NAME_UPPER}_FOUND TRUE) IF(NOT ${_VAR1}) SET(${_NAME_UPPER}_FOUND FALSE) ENDIF(NOT ${_VAR1}) FOREACH(_CURRENT_VAR ${ARGN}) IF(NOT ${_CURRENT_VAR}) SET(${_NAME_UPPER}_FOUND FALSE) ENDIF(NOT ${_CURRENT_VAR}) ENDFOREACH(_CURRENT_VAR) IF (${_NAME_UPPER}_FOUND) IF (NOT ${_NAME}_FIND_QUIETLY) MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}") ENDIF (NOT ${_NAME}_FIND_QUIETLY) ELSE (${_NAME_UPPER}_FOUND) IF (${_NAME}_FIND_REQUIRED) MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}") ELSE (${_NAME}_FIND_REQUIRED) IF (NOT ${_NAME}_FIND_QUIETLY) MESSAGE(STATUS "${_FAIL_MESSAGE}") ENDIF (NOT ${_NAME}_FIND_QUIETLY) ENDIF (${_NAME}_FIND_REQUIRED) ENDIF (${_NAME_UPPER}_FOUND) ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS) pcre-8.31/cmake/FindEditline.cmake0000644000222100022210000000122111722463372013726 00000000000000# Modified from FindReadline.cmake (PH Feb 2012) if(EDITLINE_INCLUDE_DIR AND EDITLINE_LIBRARY AND NCURSES_LIBRARY) set(EDITLINE_FOUND TRUE) else(EDITLINE_INCLUDE_DIR AND EDITLINE_LIBRARY AND NCURSES_LIBRARY) FIND_PATH(EDITLINE_INCLUDE_DIR readline.h /usr/include/editline /usr/include/edit/readline /usr/include/readline ) FIND_LIBRARY(EDITLINE_LIBRARY NAMES edit) include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Editline DEFAULT_MSG EDITLINE_INCLUDE_DIR EDITLINE_LIBRARY ) MARK_AS_ADVANCED(EDITLINE_INCLUDE_DIR EDITLINE_LIBRARY) endif(EDITLINE_INCLUDE_DIR AND EDITLINE_LIBRARY AND NCURSES_LIBRARY) pcre-8.31/cmake/FindReadline.cmake0000644000222100022210000000240711003326142013704 00000000000000# from http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/FindReadline.cmake # http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/COPYING-CMAKE-SCRIPTS # --> BSD licensed # # GNU Readline library finder if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) set(READLINE_FOUND TRUE) else(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) FIND_PATH(READLINE_INCLUDE_DIR readline/readline.h /usr/include/readline ) # 2008-04-22 The next clause used to read like this: # # FIND_LIBRARY(READLINE_LIBRARY NAMES readline) # FIND_LIBRARY(NCURSES_LIBRARY NAMES ncurses ) # include(FindPackageHandleStandardArgs) # FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG NCURSES_LIBRARY READLINE_INCLUDE_DIR READLINE_LIBRARY ) # # I was advised to modify it such that it will find an ncurses library if # required, but not if one was explicitly given, that is, it allows the # default to be overridden. PH FIND_LIBRARY(READLINE_LIBRARY NAMES readline) include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY ) MARK_AS_ADVANCED(READLINE_INCLUDE_DIR READLINE_LIBRARY) endif(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) pcre-8.31/cmake/COPYING-CMAKE-SCRIPTS0000644000222100022210000000245710744057742013403 00000000000000Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pcre-8.31/aclocal.m40000644000222100022210000122640311775524606011170 00000000000000# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, [m4_warning([this file was generated for autoconf 2.68. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010 Free Software Foundation, # Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010 Free Software Foundation, # Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2010 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi # Handle Gentoo/FreeBSD as it was Linux case $host_vendor in gentoo) version_type=linux ;; *) version_type=freebsd-$objformat ;; esac case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; linux) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' need_lib_prefix=no need_version=no ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; haiku*) version_type=linux need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ F* | *Sun*Fortran*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], [[If ld is used when linking, flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3293 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4]) m4_define([LT_PACKAGE_REVISION], [1.3293]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4' macro_revision='1.3293' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # (`yes' being less verbose, `no' or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [ --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0')]) case $enable_silent_rules in yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR pcre-8.31/pcre_byte_order.c0000644000222100022210000001757111701567032012633 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains an internal function that tests a compiled pattern to see if it was compiled with the opposite endianness. If so, it uses an auxiliary local function to flip the appropriate bytes. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Swap byte functions * *************************************************/ /* The following functions swap the bytes of a pcre_uint16 and pcre_uint32 value. Arguments: value any number Returns: the byte swapped value */ static pcre_uint32 swap_uint32(pcre_uint32 value) { return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | (value >> 24); } static pcre_uint16 swap_uint16(pcre_uint16 value) { return (value >> 8) | (value << 8); } /************************************************* * Test for a byte-flipped compiled regex * *************************************************/ /* This function swaps the bytes of a compiled pattern usually loaded form the disk. It also sets the tables pointer, which is likely an invalid pointer after reload. Arguments: argument_re points to the compiled expression extra_data points to extra data or is NULL tables points to the character tables or NULL Returns: 0 if the swap is successful, negative on error */ #ifdef COMPILE_PCRE8 PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re, pcre_extra *extra_data, const unsigned char *tables) #else PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re, pcre16_extra *extra_data, const unsigned char *tables) #endif { REAL_PCRE *re = (REAL_PCRE *)argument_re; pcre_study_data *study; #ifndef COMPILE_PCRE8 pcre_uchar *ptr; int length; #ifdef SUPPORT_UTF BOOL utf; BOOL utf16_char; #endif /* SUPPORT_UTF */ #endif /* !COMPILE_PCRE8 */ if (re == NULL) return PCRE_ERROR_NULL; if (re->magic_number == MAGIC_NUMBER) { if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; re->tables = tables; return 0; } if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; re->magic_number = MAGIC_NUMBER; re->size = swap_uint32(re->size); re->options = swap_uint32(re->options); re->flags = swap_uint16(re->flags); re->top_bracket = swap_uint16(re->top_bracket); re->top_backref = swap_uint16(re->top_backref); re->first_char = swap_uint16(re->first_char); re->req_char = swap_uint16(re->req_char); re->name_table_offset = swap_uint16(re->name_table_offset); re->name_entry_size = swap_uint16(re->name_entry_size); re->name_count = swap_uint16(re->name_count); re->ref_count = swap_uint16(re->ref_count); re->tables = tables; if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) { study = (pcre_study_data *)extra_data->study_data; study->size = swap_uint32(study->size); study->flags = swap_uint32(study->flags); study->minlength = swap_uint32(study->minlength); } #ifndef COMPILE_PCRE8 ptr = (pcre_uchar *)re + re->name_table_offset; length = re->name_count * re->name_entry_size; #ifdef SUPPORT_UTF utf = (re->options & PCRE_UTF16) != 0; utf16_char = FALSE; #endif while(TRUE) { /* Swap previous characters. */ while (length-- > 0) { *ptr = swap_uint16(*ptr); ptr++; } #ifdef SUPPORT_UTF if (utf16_char) { if (HAS_EXTRALEN(ptr[-1])) { /* We know that there is only one extra character in UTF-16. */ *ptr = swap_uint16(*ptr); ptr++; } } utf16_char = FALSE; #endif /* SUPPORT_UTF */ /* Get next opcode. */ length = 0; *ptr = swap_uint16(*ptr); switch (*ptr) { case OP_END: return 0; #ifdef SUPPORT_UTF case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: case OP_UPTO: case OP_MINUPTO: case OP_EXACT: case OP_POSSTAR: case OP_POSPLUS: case OP_POSQUERY: case OP_POSUPTO: case OP_STARI: case OP_MINSTARI: case OP_PLUSI: case OP_MINPLUSI: case OP_QUERYI: case OP_MINQUERYI: case OP_UPTOI: case OP_MINUPTOI: case OP_EXACTI: case OP_POSSTARI: case OP_POSPLUSI: case OP_POSQUERYI: case OP_POSUPTOI: case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTEXACT: case OP_NOTPOSSTAR: case OP_NOTPOSPLUS: case OP_NOTPOSQUERY: case OP_NOTPOSUPTO: case OP_NOTSTARI: case OP_NOTMINSTARI: case OP_NOTPLUSI: case OP_NOTMINPLUSI: case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTUPTOI: case OP_NOTMINUPTOI: case OP_NOTEXACTI: case OP_NOTPOSSTARI: case OP_NOTPOSPLUSI: case OP_NOTPOSQUERYI: case OP_NOTPOSUPTOI: if (utf) utf16_char = TRUE; #endif /* Fall through. */ default: length = PRIV(OP_lengths)[*ptr] - 1; break; case OP_CLASS: case OP_NCLASS: /* Skip the character bit map. */ ptr += 32/sizeof(pcre_uchar); length = 0; break; case OP_XCLASS: /* Reverse the size of the XCLASS instance. */ ptr++; *ptr = swap_uint16(*ptr); if (LINK_SIZE > 1) { /* LINK_SIZE can be 1 or 2 in 16 bit mode. */ ptr++; *ptr = swap_uint16(*ptr); } ptr++; length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1); *ptr = swap_uint16(*ptr); if ((*ptr & XCL_MAP) != 0) { /* Skip the character bit map. */ ptr += 32/sizeof(pcre_uchar); length -= 32/sizeof(pcre_uchar); } break; } ptr++; } /* Control should never reach here in 16 bit mode. */ #endif /* !COMPILE_PCRE8 */ return 0; } /* End of pcre_byte_order.c */ pcre-8.31/pcre_ucd.c0000644000222100022210000051627311723162503011251 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /* Unicode character database. */ /* This file was autogenerated by the MultiStage2.py script. */ /* Total size: 62904 bytes, block size: 128. */ /* The tables herein are needed only when UCP support is built */ /* into PCRE. This module should not be referenced otherwise, so */ /* it should not matter whether it is compiled or not. However */ /* a comment was received about space saving - maybe the guy linked */ /* all the modules rather than using a library - so we include a */ /* condition to cut out the tables when not needed. But don't leave */ /* a totally empty module because some compilers barf at that. */ /* Instead, just supply small dummy tables. */ #ifndef SUPPORT_UCP const ucd_record PRIV(ucd_records)[] = {{0,0,0 }}; const pcre_uint8 PRIV(ucd_stage1)[] = {0}; const pcre_uint16 PRIV(ucd_stage2)[] = {0}; #else /* When recompiling tables with a new Unicode version, please check types in the structure definition from pcre_internal.h: typedef struct { pcre_uint8 property_0; pcre_uint8 property_1; pcre_int32 property_2; } ucd_record; */ const ucd_record PRIV(ucd_records)[] = { /* 4536 bytes, record size 8 */ { 9, 0, 0, }, /* 0 */ { 9, 29, 0, }, /* 1 */ { 9, 21, 0, }, /* 2 */ { 9, 23, 0, }, /* 3 */ { 9, 22, 0, }, /* 4 */ { 9, 18, 0, }, /* 5 */ { 9, 25, 0, }, /* 6 */ { 9, 17, 0, }, /* 7 */ { 9, 13, 0, }, /* 8 */ { 33, 9, 32, }, /* 9 */ { 9, 24, 0, }, /* 10 */ { 9, 16, 0, }, /* 11 */ { 33, 5, -32, }, /* 12 */ { 9, 26, 0, }, /* 13 */ { 33, 7, 0, }, /* 14 */ { 9, 20, 0, }, /* 15 */ { 9, 1, 0, }, /* 16 */ { 9, 15, 0, }, /* 17 */ { 9, 5, 743, }, /* 18 */ { 9, 19, 0, }, /* 19 */ { 33, 5, 0, }, /* 20 */ { 33, 5, 121, }, /* 21 */ { 33, 9, 1, }, /* 22 */ { 33, 5, -1, }, /* 23 */ { 33, 9, -199, }, /* 24 */ { 33, 5, -232, }, /* 25 */ { 33, 9, -121, }, /* 26 */ { 33, 5, -300, }, /* 27 */ { 33, 5, 195, }, /* 28 */ { 33, 9, 210, }, /* 29 */ { 33, 9, 206, }, /* 30 */ { 33, 9, 205, }, /* 31 */ { 33, 9, 79, }, /* 32 */ { 33, 9, 202, }, /* 33 */ { 33, 9, 203, }, /* 34 */ { 33, 9, 207, }, /* 35 */ { 33, 5, 97, }, /* 36 */ { 33, 9, 211, }, /* 37 */ { 33, 9, 209, }, /* 38 */ { 33, 5, 163, }, /* 39 */ { 33, 9, 213, }, /* 40 */ { 33, 5, 130, }, /* 41 */ { 33, 9, 214, }, /* 42 */ { 33, 9, 218, }, /* 43 */ { 33, 9, 217, }, /* 44 */ { 33, 9, 219, }, /* 45 */ { 33, 5, 56, }, /* 46 */ { 33, 9, 2, }, /* 47 */ { 33, 8, -1, }, /* 48 */ { 33, 5, -2, }, /* 49 */ { 33, 5, -79, }, /* 50 */ { 33, 9, -97, }, /* 51 */ { 33, 9, -56, }, /* 52 */ { 33, 9, -130, }, /* 53 */ { 33, 9, 10795, }, /* 54 */ { 33, 9, -163, }, /* 55 */ { 33, 9, 10792, }, /* 56 */ { 33, 5, 10815, }, /* 57 */ { 33, 9, -195, }, /* 58 */ { 33, 9, 69, }, /* 59 */ { 33, 9, 71, }, /* 60 */ { 33, 5, 10783, }, /* 61 */ { 33, 5, 10780, }, /* 62 */ { 33, 5, 10782, }, /* 63 */ { 33, 5, -210, }, /* 64 */ { 33, 5, -206, }, /* 65 */ { 33, 5, -205, }, /* 66 */ { 33, 5, -202, }, /* 67 */ { 33, 5, -203, }, /* 68 */ { 33, 5, -207, }, /* 69 */ { 33, 5, 42280, }, /* 70 */ { 33, 5, 42308, }, /* 71 */ { 33, 5, -209, }, /* 72 */ { 33, 5, -211, }, /* 73 */ { 33, 5, 10743, }, /* 74 */ { 33, 5, 10749, }, /* 75 */ { 33, 5, -213, }, /* 76 */ { 33, 5, -214, }, /* 77 */ { 33, 5, 10727, }, /* 78 */ { 33, 5, -218, }, /* 79 */ { 33, 5, -69, }, /* 80 */ { 33, 5, -217, }, /* 81 */ { 33, 5, -71, }, /* 82 */ { 33, 5, -219, }, /* 83 */ { 33, 6, 0, }, /* 84 */ { 9, 6, 0, }, /* 85 */ { 3, 24, 0, }, /* 86 */ { 27, 12, 0, }, /* 87 */ { 27, 12, 84, }, /* 88 */ { 19, 9, 1, }, /* 89 */ { 19, 5, -1, }, /* 90 */ { 19, 24, 0, }, /* 91 */ { 9, 2, 0, }, /* 92 */ { 19, 6, 0, }, /* 93 */ { 19, 5, 130, }, /* 94 */ { 19, 9, 38, }, /* 95 */ { 19, 9, 37, }, /* 96 */ { 19, 9, 64, }, /* 97 */ { 19, 9, 63, }, /* 98 */ { 19, 5, 0, }, /* 99 */ { 19, 9, 32, }, /* 100 */ { 19, 5, -38, }, /* 101 */ { 19, 5, -37, }, /* 102 */ { 19, 5, -32, }, /* 103 */ { 19, 5, -31, }, /* 104 */ { 19, 5, -64, }, /* 105 */ { 19, 5, -63, }, /* 106 */ { 19, 9, 8, }, /* 107 */ { 19, 5, -62, }, /* 108 */ { 19, 5, -57, }, /* 109 */ { 19, 9, 0, }, /* 110 */ { 19, 5, -47, }, /* 111 */ { 19, 5, -54, }, /* 112 */ { 19, 5, -8, }, /* 113 */ { 10, 9, 1, }, /* 114 */ { 10, 5, -1, }, /* 115 */ { 19, 5, -86, }, /* 116 */ { 19, 5, -80, }, /* 117 */ { 19, 5, 7, }, /* 118 */ { 19, 9, -60, }, /* 119 */ { 19, 5, -96, }, /* 120 */ { 19, 25, 0, }, /* 121 */ { 19, 9, -7, }, /* 122 */ { 19, 9, -130, }, /* 123 */ { 12, 9, 80, }, /* 124 */ { 12, 9, 32, }, /* 125 */ { 12, 5, -32, }, /* 126 */ { 12, 5, -80, }, /* 127 */ { 12, 9, 1, }, /* 128 */ { 12, 5, -1, }, /* 129 */ { 12, 26, 0, }, /* 130 */ { 12, 12, 0, }, /* 131 */ { 12, 11, 0, }, /* 132 */ { 12, 9, 15, }, /* 133 */ { 12, 5, -15, }, /* 134 */ { 1, 9, 48, }, /* 135 */ { 1, 6, 0, }, /* 136 */ { 1, 21, 0, }, /* 137 */ { 1, 5, -48, }, /* 138 */ { 1, 5, 0, }, /* 139 */ { 1, 17, 0, }, /* 140 */ { 1, 23, 0, }, /* 141 */ { 25, 12, 0, }, /* 142 */ { 25, 17, 0, }, /* 143 */ { 25, 21, 0, }, /* 144 */ { 25, 7, 0, }, /* 145 */ { 0, 1, 0, }, /* 146 */ { 0, 25, 0, }, /* 147 */ { 0, 21, 0, }, /* 148 */ { 0, 23, 0, }, /* 149 */ { 0, 26, 0, }, /* 150 */ { 0, 12, 0, }, /* 151 */ { 0, 7, 0, }, /* 152 */ { 0, 6, 0, }, /* 153 */ { 0, 13, 0, }, /* 154 */ { 49, 21, 0, }, /* 155 */ { 49, 1, 0, }, /* 156 */ { 49, 7, 0, }, /* 157 */ { 49, 12, 0, }, /* 158 */ { 55, 7, 0, }, /* 159 */ { 55, 12, 0, }, /* 160 */ { 63, 13, 0, }, /* 161 */ { 63, 7, 0, }, /* 162 */ { 63, 12, 0, }, /* 163 */ { 63, 6, 0, }, /* 164 */ { 63, 26, 0, }, /* 165 */ { 63, 21, 0, }, /* 166 */ { 89, 7, 0, }, /* 167 */ { 89, 12, 0, }, /* 168 */ { 89, 6, 0, }, /* 169 */ { 89, 21, 0, }, /* 170 */ { 94, 7, 0, }, /* 171 */ { 94, 12, 0, }, /* 172 */ { 94, 21, 0, }, /* 173 */ { 14, 12, 0, }, /* 174 */ { 14, 10, 0, }, /* 175 */ { 14, 7, 0, }, /* 176 */ { 14, 13, 0, }, /* 177 */ { 14, 21, 0, }, /* 178 */ { 14, 6, 0, }, /* 179 */ { 2, 12, 0, }, /* 180 */ { 2, 10, 0, }, /* 181 */ { 2, 7, 0, }, /* 182 */ { 2, 13, 0, }, /* 183 */ { 2, 23, 0, }, /* 184 */ { 2, 15, 0, }, /* 185 */ { 2, 26, 0, }, /* 186 */ { 21, 12, 0, }, /* 187 */ { 21, 10, 0, }, /* 188 */ { 21, 7, 0, }, /* 189 */ { 21, 13, 0, }, /* 190 */ { 20, 12, 0, }, /* 191 */ { 20, 10, 0, }, /* 192 */ { 20, 7, 0, }, /* 193 */ { 20, 13, 0, }, /* 194 */ { 20, 21, 0, }, /* 195 */ { 20, 23, 0, }, /* 196 */ { 43, 12, 0, }, /* 197 */ { 43, 10, 0, }, /* 198 */ { 43, 7, 0, }, /* 199 */ { 43, 13, 0, }, /* 200 */ { 43, 26, 0, }, /* 201 */ { 43, 15, 0, }, /* 202 */ { 53, 12, 0, }, /* 203 */ { 53, 7, 0, }, /* 204 */ { 53, 10, 0, }, /* 205 */ { 53, 13, 0, }, /* 206 */ { 53, 15, 0, }, /* 207 */ { 53, 26, 0, }, /* 208 */ { 53, 23, 0, }, /* 209 */ { 54, 10, 0, }, /* 210 */ { 54, 7, 0, }, /* 211 */ { 54, 12, 0, }, /* 212 */ { 54, 13, 0, }, /* 213 */ { 54, 15, 0, }, /* 214 */ { 54, 26, 0, }, /* 215 */ { 28, 10, 0, }, /* 216 */ { 28, 7, 0, }, /* 217 */ { 28, 12, 0, }, /* 218 */ { 28, 13, 0, }, /* 219 */ { 36, 10, 0, }, /* 220 */ { 36, 7, 0, }, /* 221 */ { 36, 12, 0, }, /* 222 */ { 36, 13, 0, }, /* 223 */ { 36, 15, 0, }, /* 224 */ { 36, 26, 0, }, /* 225 */ { 47, 10, 0, }, /* 226 */ { 47, 7, 0, }, /* 227 */ { 47, 12, 0, }, /* 228 */ { 47, 21, 0, }, /* 229 */ { 56, 7, 0, }, /* 230 */ { 56, 12, 0, }, /* 231 */ { 56, 6, 0, }, /* 232 */ { 56, 21, 0, }, /* 233 */ { 56, 13, 0, }, /* 234 */ { 32, 7, 0, }, /* 235 */ { 32, 12, 0, }, /* 236 */ { 32, 6, 0, }, /* 237 */ { 32, 13, 0, }, /* 238 */ { 57, 7, 0, }, /* 239 */ { 57, 26, 0, }, /* 240 */ { 57, 21, 0, }, /* 241 */ { 57, 12, 0, }, /* 242 */ { 57, 13, 0, }, /* 243 */ { 57, 15, 0, }, /* 244 */ { 57, 22, 0, }, /* 245 */ { 57, 18, 0, }, /* 246 */ { 57, 10, 0, }, /* 247 */ { 38, 7, 0, }, /* 248 */ { 38, 10, 0, }, /* 249 */ { 38, 12, 0, }, /* 250 */ { 38, 13, 0, }, /* 251 */ { 38, 21, 0, }, /* 252 */ { 38, 26, 0, }, /* 253 */ { 16, 9, 7264, }, /* 254 */ { 16, 7, 0, }, /* 255 */ { 16, 6, 0, }, /* 256 */ { 23, 7, 0, }, /* 257 */ { 15, 7, 0, }, /* 258 */ { 15, 12, 0, }, /* 259 */ { 15, 21, 0, }, /* 260 */ { 15, 15, 0, }, /* 261 */ { 15, 26, 0, }, /* 262 */ { 8, 7, 0, }, /* 263 */ { 7, 17, 0, }, /* 264 */ { 7, 7, 0, }, /* 265 */ { 7, 21, 0, }, /* 266 */ { 40, 29, 0, }, /* 267 */ { 40, 7, 0, }, /* 268 */ { 40, 22, 0, }, /* 269 */ { 40, 18, 0, }, /* 270 */ { 45, 7, 0, }, /* 271 */ { 45, 14, 0, }, /* 272 */ { 50, 7, 0, }, /* 273 */ { 50, 12, 0, }, /* 274 */ { 24, 7, 0, }, /* 275 */ { 24, 12, 0, }, /* 276 */ { 6, 7, 0, }, /* 277 */ { 6, 12, 0, }, /* 278 */ { 51, 7, 0, }, /* 279 */ { 51, 12, 0, }, /* 280 */ { 31, 7, 0, }, /* 281 */ { 31, 12, 0, }, /* 282 */ { 31, 10, 0, }, /* 283 */ { 31, 21, 0, }, /* 284 */ { 31, 6, 0, }, /* 285 */ { 31, 23, 0, }, /* 286 */ { 31, 13, 0, }, /* 287 */ { 31, 15, 0, }, /* 288 */ { 37, 21, 0, }, /* 289 */ { 37, 17, 0, }, /* 290 */ { 37, 12, 0, }, /* 291 */ { 37, 29, 0, }, /* 292 */ { 37, 13, 0, }, /* 293 */ { 37, 7, 0, }, /* 294 */ { 37, 6, 0, }, /* 295 */ { 34, 7, 0, }, /* 296 */ { 34, 12, 0, }, /* 297 */ { 34, 10, 0, }, /* 298 */ { 34, 26, 0, }, /* 299 */ { 34, 21, 0, }, /* 300 */ { 34, 13, 0, }, /* 301 */ { 52, 7, 0, }, /* 302 */ { 39, 7, 0, }, /* 303 */ { 39, 10, 0, }, /* 304 */ { 39, 13, 0, }, /* 305 */ { 39, 15, 0, }, /* 306 */ { 39, 26, 0, }, /* 307 */ { 31, 26, 0, }, /* 308 */ { 5, 7, 0, }, /* 309 */ { 5, 12, 0, }, /* 310 */ { 5, 10, 0, }, /* 311 */ { 5, 21, 0, }, /* 312 */ { 90, 7, 0, }, /* 313 */ { 90, 10, 0, }, /* 314 */ { 90, 12, 0, }, /* 315 */ { 90, 13, 0, }, /* 316 */ { 90, 21, 0, }, /* 317 */ { 90, 6, 0, }, /* 318 */ { 61, 12, 0, }, /* 319 */ { 61, 10, 0, }, /* 320 */ { 61, 7, 0, }, /* 321 */ { 61, 13, 0, }, /* 322 */ { 61, 21, 0, }, /* 323 */ { 61, 26, 0, }, /* 324 */ { 75, 12, 0, }, /* 325 */ { 75, 10, 0, }, /* 326 */ { 75, 7, 0, }, /* 327 */ { 75, 13, 0, }, /* 328 */ { 92, 7, 0, }, /* 329 */ { 92, 12, 0, }, /* 330 */ { 92, 10, 0, }, /* 331 */ { 92, 21, 0, }, /* 332 */ { 69, 7, 0, }, /* 333 */ { 69, 10, 0, }, /* 334 */ { 69, 12, 0, }, /* 335 */ { 69, 21, 0, }, /* 336 */ { 69, 13, 0, }, /* 337 */ { 72, 13, 0, }, /* 338 */ { 72, 7, 0, }, /* 339 */ { 72, 6, 0, }, /* 340 */ { 72, 21, 0, }, /* 341 */ { 75, 21, 0, }, /* 342 */ { 9, 10, 0, }, /* 343 */ { 9, 7, 0, }, /* 344 */ { 12, 5, 0, }, /* 345 */ { 12, 6, 0, }, /* 346 */ { 33, 5, 35332, }, /* 347 */ { 33, 5, 3814, }, /* 348 */ { 33, 5, -59, }, /* 349 */ { 33, 9, -7615, }, /* 350 */ { 19, 5, 8, }, /* 351 */ { 19, 9, -8, }, /* 352 */ { 19, 5, 74, }, /* 353 */ { 19, 5, 86, }, /* 354 */ { 19, 5, 100, }, /* 355 */ { 19, 5, 128, }, /* 356 */ { 19, 5, 112, }, /* 357 */ { 19, 5, 126, }, /* 358 */ { 19, 8, -8, }, /* 359 */ { 19, 5, 9, }, /* 360 */ { 19, 9, -74, }, /* 361 */ { 19, 8, -9, }, /* 362 */ { 19, 5, -7205, }, /* 363 */ { 19, 9, -86, }, /* 364 */ { 19, 9, -100, }, /* 365 */ { 19, 9, -112, }, /* 366 */ { 19, 9, -128, }, /* 367 */ { 19, 9, -126, }, /* 368 */ { 27, 1, 0, }, /* 369 */ { 9, 27, 0, }, /* 370 */ { 9, 28, 0, }, /* 371 */ { 27, 11, 0, }, /* 372 */ { 9, 9, 0, }, /* 373 */ { 9, 5, 0, }, /* 374 */ { 19, 9, -7517, }, /* 375 */ { 33, 9, -8383, }, /* 376 */ { 33, 9, -8262, }, /* 377 */ { 33, 9, 28, }, /* 378 */ { 33, 5, -28, }, /* 379 */ { 33, 14, 16, }, /* 380 */ { 33, 14, -16, }, /* 381 */ { 33, 14, 0, }, /* 382 */ { 9, 26, 26, }, /* 383 */ { 9, 26, -26, }, /* 384 */ { 4, 26, 0, }, /* 385 */ { 17, 9, 48, }, /* 386 */ { 17, 5, -48, }, /* 387 */ { 33, 9, -10743, }, /* 388 */ { 33, 9, -3814, }, /* 389 */ { 33, 9, -10727, }, /* 390 */ { 33, 5, -10795, }, /* 391 */ { 33, 5, -10792, }, /* 392 */ { 33, 9, -10780, }, /* 393 */ { 33, 9, -10749, }, /* 394 */ { 33, 9, -10783, }, /* 395 */ { 33, 9, -10782, }, /* 396 */ { 33, 9, -10815, }, /* 397 */ { 10, 5, 0, }, /* 398 */ { 10, 26, 0, }, /* 399 */ { 10, 12, 0, }, /* 400 */ { 10, 21, 0, }, /* 401 */ { 10, 15, 0, }, /* 402 */ { 16, 5, -7264, }, /* 403 */ { 58, 7, 0, }, /* 404 */ { 58, 6, 0, }, /* 405 */ { 58, 21, 0, }, /* 406 */ { 58, 12, 0, }, /* 407 */ { 22, 26, 0, }, /* 408 */ { 22, 6, 0, }, /* 409 */ { 22, 14, 0, }, /* 410 */ { 23, 10, 0, }, /* 411 */ { 26, 7, 0, }, /* 412 */ { 26, 6, 0, }, /* 413 */ { 29, 7, 0, }, /* 414 */ { 29, 6, 0, }, /* 415 */ { 3, 7, 0, }, /* 416 */ { 23, 26, 0, }, /* 417 */ { 29, 26, 0, }, /* 418 */ { 22, 7, 0, }, /* 419 */ { 60, 7, 0, }, /* 420 */ { 60, 6, 0, }, /* 421 */ { 60, 26, 0, }, /* 422 */ { 85, 7, 0, }, /* 423 */ { 85, 6, 0, }, /* 424 */ { 85, 21, 0, }, /* 425 */ { 76, 7, 0, }, /* 426 */ { 76, 6, 0, }, /* 427 */ { 76, 21, 0, }, /* 428 */ { 76, 13, 0, }, /* 429 */ { 12, 7, 0, }, /* 430 */ { 12, 21, 0, }, /* 431 */ { 78, 7, 0, }, /* 432 */ { 78, 14, 0, }, /* 433 */ { 78, 12, 0, }, /* 434 */ { 78, 21, 0, }, /* 435 */ { 33, 9, -35332, }, /* 436 */ { 33, 9, -42280, }, /* 437 */ { 33, 9, -42308, }, /* 438 */ { 48, 7, 0, }, /* 439 */ { 48, 12, 0, }, /* 440 */ { 48, 10, 0, }, /* 441 */ { 48, 26, 0, }, /* 442 */ { 64, 7, 0, }, /* 443 */ { 64, 21, 0, }, /* 444 */ { 74, 10, 0, }, /* 445 */ { 74, 7, 0, }, /* 446 */ { 74, 12, 0, }, /* 447 */ { 74, 21, 0, }, /* 448 */ { 74, 13, 0, }, /* 449 */ { 68, 13, 0, }, /* 450 */ { 68, 7, 0, }, /* 451 */ { 68, 12, 0, }, /* 452 */ { 68, 21, 0, }, /* 453 */ { 73, 7, 0, }, /* 454 */ { 73, 12, 0, }, /* 455 */ { 73, 10, 0, }, /* 456 */ { 73, 21, 0, }, /* 457 */ { 83, 12, 0, }, /* 458 */ { 83, 10, 0, }, /* 459 */ { 83, 7, 0, }, /* 460 */ { 83, 21, 0, }, /* 461 */ { 83, 6, 0, }, /* 462 */ { 83, 13, 0, }, /* 463 */ { 67, 7, 0, }, /* 464 */ { 67, 12, 0, }, /* 465 */ { 67, 10, 0, }, /* 466 */ { 67, 13, 0, }, /* 467 */ { 67, 21, 0, }, /* 468 */ { 38, 6, 0, }, /* 469 */ { 91, 7, 0, }, /* 470 */ { 91, 12, 0, }, /* 471 */ { 91, 6, 0, }, /* 472 */ { 91, 21, 0, }, /* 473 */ { 86, 7, 0, }, /* 474 */ { 86, 10, 0, }, /* 475 */ { 86, 12, 0, }, /* 476 */ { 86, 21, 0, }, /* 477 */ { 86, 6, 0, }, /* 478 */ { 86, 13, 0, }, /* 479 */ { 9, 4, 0, }, /* 480 */ { 9, 3, 0, }, /* 481 */ { 25, 25, 0, }, /* 482 */ { 0, 24, 0, }, /* 483 */ { 35, 7, 0, }, /* 484 */ { 19, 14, 0, }, /* 485 */ { 19, 15, 0, }, /* 486 */ { 19, 26, 0, }, /* 487 */ { 70, 7, 0, }, /* 488 */ { 66, 7, 0, }, /* 489 */ { 41, 7, 0, }, /* 490 */ { 41, 15, 0, }, /* 491 */ { 18, 7, 0, }, /* 492 */ { 18, 14, 0, }, /* 493 */ { 59, 7, 0, }, /* 494 */ { 59, 21, 0, }, /* 495 */ { 42, 7, 0, }, /* 496 */ { 42, 21, 0, }, /* 497 */ { 42, 14, 0, }, /* 498 */ { 13, 9, 40, }, /* 499 */ { 13, 5, -40, }, /* 500 */ { 46, 7, 0, }, /* 501 */ { 44, 7, 0, }, /* 502 */ { 44, 13, 0, }, /* 503 */ { 11, 7, 0, }, /* 504 */ { 80, 7, 0, }, /* 505 */ { 80, 21, 0, }, /* 506 */ { 80, 15, 0, }, /* 507 */ { 65, 7, 0, }, /* 508 */ { 65, 15, 0, }, /* 509 */ { 65, 21, 0, }, /* 510 */ { 71, 7, 0, }, /* 511 */ { 71, 21, 0, }, /* 512 */ { 97, 7, 0, }, /* 513 */ { 96, 7, 0, }, /* 514 */ { 30, 7, 0, }, /* 515 */ { 30, 12, 0, }, /* 516 */ { 30, 15, 0, }, /* 517 */ { 30, 21, 0, }, /* 518 */ { 87, 7, 0, }, /* 519 */ { 87, 15, 0, }, /* 520 */ { 87, 21, 0, }, /* 521 */ { 77, 7, 0, }, /* 522 */ { 77, 21, 0, }, /* 523 */ { 82, 7, 0, }, /* 524 */ { 82, 15, 0, }, /* 525 */ { 81, 7, 0, }, /* 526 */ { 81, 15, 0, }, /* 527 */ { 88, 7, 0, }, /* 528 */ { 0, 15, 0, }, /* 529 */ { 93, 10, 0, }, /* 530 */ { 93, 12, 0, }, /* 531 */ { 93, 7, 0, }, /* 532 */ { 93, 21, 0, }, /* 533 */ { 93, 15, 0, }, /* 534 */ { 93, 13, 0, }, /* 535 */ { 84, 12, 0, }, /* 536 */ { 84, 10, 0, }, /* 537 */ { 84, 7, 0, }, /* 538 */ { 84, 21, 0, }, /* 539 */ { 84, 1, 0, }, /* 540 */ { 100, 7, 0, }, /* 541 */ { 100, 13, 0, }, /* 542 */ { 95, 12, 0, }, /* 543 */ { 95, 7, 0, }, /* 544 */ { 95, 10, 0, }, /* 545 */ { 95, 13, 0, }, /* 546 */ { 95, 21, 0, }, /* 547 */ { 99, 12, 0, }, /* 548 */ { 99, 10, 0, }, /* 549 */ { 99, 7, 0, }, /* 550 */ { 99, 21, 0, }, /* 551 */ { 99, 13, 0, }, /* 552 */ { 101, 7, 0, }, /* 553 */ { 101, 12, 0, }, /* 554 */ { 101, 10, 0, }, /* 555 */ { 101, 13, 0, }, /* 556 */ { 62, 7, 0, }, /* 557 */ { 62, 14, 0, }, /* 558 */ { 62, 21, 0, }, /* 559 */ { 79, 7, 0, }, /* 560 */ { 98, 7, 0, }, /* 561 */ { 98, 10, 0, }, /* 562 */ { 98, 12, 0, }, /* 563 */ { 98, 6, 0, }, /* 564 */ { 19, 12, 0, }, /* 565 */ { 26, 26, 0, }, /* 566 */ }; const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */ 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40, 40, 41, 42, 43, 44, /* U+1000 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, /* U+1800 */ 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 70, 73, 74, /* U+2000 */ 75, 75, 65, 76, 65, 65, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, /* U+2800 */ 87, 88, 89, 90, 91, 92, 93, 70, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+4000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 94, 94, 94, 94, /* U+4800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+5000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+5800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+6000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+6800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+7000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+7800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+8000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+8800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+9000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 96, /* U+9800 */ 97, 98, 98, 98, 98, 98, 98, 98, 98, 99,100,100,101,102,103,104, /* U+A000 */ 105,106,107,108,109,110,111,112, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B000 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B800 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C000 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C800 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,113, /* U+D000 */ 114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+D800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F000 */ 115,115, 94, 94,116,117,118,119,120,120,121,122,123,124,125,126, /* U+F800 */ 127,128,129,130, 78,131,132,133,134,135, 78, 78, 78, 78, 78, 78, /* U+10000 */ 136, 78,137,138,139, 78,140, 78,141, 78, 78, 78,142, 78, 78, 78, /* U+10800 */ 143,144,145,146, 78, 78, 78, 78, 78, 78, 78, 78, 78,147, 78, 78, /* U+11000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+11800 */ 148,148,148,148,148,148,149, 78,150, 78, 78, 78, 78, 78, 78, 78, /* U+12000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+12800 */ 151,151,151,151,151,151,151,151,152, 78, 78, 78, 78, 78, 78, 78, /* U+13000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+13800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+16000 */ 153,153,153,153,154, 78, 78, 78, 78, 78, 78, 78, 78, 78,155,156, /* U+16800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A800 */ 157, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C800 */ 70,158,159,160,161, 78,162, 78,163,164,165,166,167,168,169,170, /* U+1D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,171,172, 78, 78, /* U+1E800 */ 173,174,175,176,177, 78,178,179,180,181,182,183,184,185,186, 78, /* U+1F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1F800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+21000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+21800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+22000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+22800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+23000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+23800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+24000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+24800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+25000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+25800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+26000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+26800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+27000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+27800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+28000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+28800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,187, 94, 94, /* U+2A000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+2A800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,188, 94, /* U+2B000 */ 189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F000 */ 94, 94, 94, 94,189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF800 */ 190, 78,191,192, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE800 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF000 */ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FF000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+FF800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E800 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10F000 */ 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+10F800 */ }; const pcre_uint16 PRIV(ucd_stage2)[] = { /* 49664 bytes, block = 128 */ /* block 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 0, /* block 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 13, 2, 10, 13, 14, 15, 6, 16, 13, 10, 13, 6, 17, 17, 10, 18, 2, 2, 10, 17, 14, 19, 17, 17, 17, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 20, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 21, /* block 2 */ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 24, 25, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 26, 22, 23, 22, 23, 22, 23, 27, /* block 3 */ 28, 29, 22, 23, 22, 23, 30, 22, 23, 31, 31, 22, 23, 20, 32, 33, 34, 22, 23, 31, 35, 36, 37, 38, 22, 23, 39, 20, 37, 40, 41, 42, 22, 23, 22, 23, 22, 23, 43, 22, 23, 43, 20, 20, 22, 23, 43, 22, 23, 44, 44, 22, 23, 22, 23, 45, 22, 23, 20, 14, 22, 23, 20, 46, 14, 14, 14, 14, 47, 48, 49, 47, 48, 49, 47, 48, 49, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 50, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 47, 48, 49, 22, 23, 51, 52, 22, 23, 22, 23, 22, 23, 22, 23, /* block 4 */ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 53, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 20, 20, 20, 20, 20, 54, 22, 23, 55, 56, 57, 57, 22, 23, 58, 59, 60, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 61, 62, 63, 64, 65, 20, 66, 66, 20, 67, 20, 68, 20, 20, 20, 20, 66, 20, 20, 69, 20, 70, 71, 20, 72, 73, 20, 74, 20, 20, 20, 73, 20, 75, 76, 20, 20, 77, 20, 20, 20, 20, 20, 20, 20, 78, 20, 20, /* block 5 */ 79, 20, 20, 79, 20, 20, 20, 20, 79, 80, 81, 81, 82, 20, 20, 20, 20, 20, 83, 20, 14, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 84, 84, 84, 84, 84, 10, 10, 10, 10, 10, 86, 86, 85, 10, 85, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, /* block 6 */ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 90, 89, 90, 85, 91, 89, 90, 92, 92, 93, 94, 94, 94, 2, 92, /* block 7 */ 92, 92, 92, 92, 91, 10, 95, 2, 96, 96, 96, 92, 97, 92, 98, 98, 99,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100, 92,100,100,100,100,100,100,100,100,100,101,102,102,102, 99,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, 103,103,104,103,103,103,103,103,103,103,103,103,105,106,106,107, 108,109,110,110,110,111,112,113, 89, 90, 89, 90, 89, 90, 89, 90, 89, 90,114,115,114,115,114,115,114,115,114,115,114,115,114,115, 116,117,118, 99,119,120,121, 89, 90,122, 89, 90, 99,123,123,123, /* block 8 */ 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, 125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, 125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, /* block 9 */ 128,129,130,131,131, 87, 87,131,132,132,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 133,128,129,128,129,128,129,128,129,128,129,128,129,128,129,134, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, /* block 10 */ 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92, 92, 92,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, 135,135,135,135,135,135,135, 92, 92,136,137,137,137,137,137,137, 92,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, /* block 11 */ 138,138,138,138,138,138,138,139, 92, 2,140, 92, 92, 92, 92,141, 92,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, 142,142,142,142,142,142,142,142,142,142,142,142,142,142,143,142, 144,142,142,144,142,142,144,142, 92, 92, 92, 92, 92, 92, 92, 92, 145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, 145,145,145,145,145,145,145,145,145,145,145, 92, 92, 92, 92, 92, 145,145,145,144,144, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 12 */ 146,146,146,146,146, 92,147,147,147,148,148,149, 2,148,150,150, 151,151,151,151,151,151,151,151,151,151,151, 2, 92, 92,148, 2, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 85,152,152,152,152,152,152,152,152,152,152, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,151,151,151,151,151,151,151,151,151, 87, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,148,148,148,148,152,152, 87,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 13 */ 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,148,152,151,151,151,151,151,151,151, 16,150,151, 151,151,151,151,151,153,153,151,151,150,151,151,151,151,152,152, 154,154,154,154,154,154,154,154,154,154,152,152,152,150,150,152, /* block 14 */ 155,155,155,155,155,155,155,155,155,155,155,155,155,155, 92,156, 157,158,157,157,157,157,157,157,157,157,157,157,157,157,157,157, 157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, 158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, 158,158,158,158,158,158,158,158,158,158,158, 92, 92,157,157,157, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 15 */ 159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, 159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, 159,159,159,159,159,159,160,160,160,160,160,160,160,160,160,160, 160,159, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 161,161,161,161,161,161,161,161,161,161,162,162,162,162,162,162, 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, 162,162,162,162,162,162,162,162,162,162,162,163,163,163,163,163, 163,163,163,163,164,164,165,166,166,166,164, 92, 92, 92, 92, 92, /* block 16 */ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, 167,167,167,167,167,167,168,168,168,168,169,168,168,168,168,168, 168,168,168,168,169,168,168,168,169,168,168,168,168,168, 92, 92, 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, 92, 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, 171,171,171,171,171,171,171,171,171,172,172,172, 92, 92,173, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 17 */ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 152, 92,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,151,151,151,151,151,151,151,151,151,151,151,151, 151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, 92, /* block 18 */ 174,174,174,175,176,176,176,176,176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176,176,176,174,175,174,176,175,175, 175,174,174,174,174,174,174,174,174,175,175,175,175,174,175,175, 176, 87, 87,174,174,174,174,174,176,176,176,176,176,176,176,176, 176,176,174,174, 2, 2,177,177,177,177,177,177,177,177,177,177, 178,179,176,176,176,176,176,176, 92,176,176,176,176,176,176,176, /* block 19 */ 92,180,181,181, 92,182,182,182,182,182,182,182,182, 92, 92,182, 182, 92, 92,182,182,182,182,182,182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182,182, 92,182,182,182,182,182,182, 182, 92,182, 92, 92, 92,182,182,182,182, 92, 92,180,182,181,181, 181,180,180,180,180, 92, 92,181,181, 92, 92,181,181,180,182, 92, 92, 92, 92, 92, 92, 92, 92,181, 92, 92, 92, 92,182,182, 92,182, 182,182,180,180, 92, 92,183,183,183,183,183,183,183,183,183,183, 182,182,184,184,185,185,185,185,185,185,186,184, 92, 92, 92, 92, /* block 20 */ 92,187,187,188, 92,189,189,189,189,189,189, 92, 92, 92, 92,189, 189, 92, 92,189,189,189,189,189,189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189,189, 92,189,189,189,189,189,189, 189, 92,189,189, 92,189,189, 92,189,189, 92, 92,187, 92,188,188, 188,187,187, 92, 92, 92, 92,187,187, 92, 92,187,187,187, 92, 92, 92,187, 92, 92, 92, 92, 92, 92, 92,189,189,189,189, 92,189, 92, 92, 92, 92, 92, 92, 92,190,190,190,190,190,190,190,190,190,190, 187,187,189,189,189,187, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 21 */ 92,191,191,192, 92,193,193,193,193,193,193,193,193,193, 92,193, 193,193, 92,193,193,193,193,193,193,193,193,193,193,193,193,193, 193,193,193,193,193,193,193,193,193, 92,193,193,193,193,193,193, 193, 92,193,193, 92,193,193,193,193,193, 92, 92,191,193,192,192, 192,191,191,191,191,191, 92,191,191,192, 92,192,192,191, 92, 92, 193, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 193,193,191,191, 92, 92,194,194,194,194,194,194,194,194,194,194, 195,196, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 22 */ 92,197,198,198, 92,199,199,199,199,199,199,199,199, 92, 92,199, 199, 92, 92,199,199,199,199,199,199,199,199,199,199,199,199,199, 199,199,199,199,199,199,199,199,199, 92,199,199,199,199,199,199, 199, 92,199,199, 92,199,199,199,199,199, 92, 92,197,199,198,197, 198,197,197,197,197, 92, 92,198,198, 92, 92,198,198,197, 92, 92, 92, 92, 92, 92, 92, 92,197,198, 92, 92, 92, 92,199,199, 92,199, 199,199,197,197, 92, 92,200,200,200,200,200,200,200,200,200,200, 201,199,202,202,202,202,202,202, 92, 92, 92, 92, 92, 92, 92, 92, /* block 23 */ 92, 92,203,204, 92,204,204,204,204,204,204, 92, 92, 92,204,204, 204, 92,204,204,204,204, 92, 92, 92,204,204, 92,204, 92,204,204, 92, 92, 92,204,204, 92, 92, 92,204,204,204, 92, 92, 92,204,204, 204,204,204,204,204,204,204,204,204,204, 92, 92, 92, 92,205,205, 203,205,205, 92, 92, 92,205,205,205, 92,205,205,205,203, 92, 92, 204, 92, 92, 92, 92, 92, 92,205, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,206,206,206,206,206,206,206,206,206,206, 207,207,207,208,208,208,208,208,208,209,208, 92, 92, 92, 92, 92, /* block 24 */ 92,210,210,210, 92,211,211,211,211,211,211,211,211, 92,211,211, 211, 92,211,211,211,211,211,211,211,211,211,211,211,211,211,211, 211,211,211,211,211,211,211,211,211, 92,211,211,211,211,211,211, 211,211,211,211, 92,211,211,211,211,211, 92, 92, 92,211,212,212, 212,210,210,210,210, 92,212,212,212, 92,212,212,212,212, 92, 92, 92, 92, 92, 92, 92,212,212, 92,211,211, 92, 92, 92, 92, 92, 92, 211,211,212,212, 92, 92,213,213,213,213,213,213,213,213,213,213, 92, 92, 92, 92, 92, 92, 92, 92,214,214,214,214,214,214,214,215, /* block 25 */ 92, 92,216,216, 92,217,217,217,217,217,217,217,217, 92,217,217, 217, 92,217,217,217,217,217,217,217,217,217,217,217,217,217,217, 217,217,217,217,217,217,217,217,217, 92,217,217,217,217,217,217, 217,217,217,217, 92,217,217,217,217,217, 92, 92,218,217,216,218, 216,216,216,216,216, 92,218,216,216, 92,216,216,218,218, 92, 92, 92, 92, 92, 92, 92,216,216, 92, 92, 92, 92, 92, 92, 92,217, 92, 217,217,218,218, 92, 92,219,219,219,219,219,219,219,219,219,219, 92,217,217, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 26 */ 92, 92,220,220, 92,221,221,221,221,221,221,221,221, 92,221,221, 221, 92,221,221,221,221,221,221,221,221,221,221,221,221,221,221, 221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, 221,221,221,221,221,221,221,221,221,221,221, 92, 92,221,220,220, 220,222,222,222,222, 92,220,220,220, 92,220,220,220,222,221, 92, 92, 92, 92, 92, 92, 92, 92,220, 92, 92, 92, 92, 92, 92, 92, 92, 221,221,222,222, 92, 92,223,223,223,223,223,223,223,223,223,223, 224,224,224,224,224,224, 92, 92, 92,225,221,221,221,221,221,221, /* block 27 */ 92, 92,226,226, 92,227,227,227,227,227,227,227,227,227,227,227, 227,227,227,227,227,227,227, 92, 92, 92,227,227,227,227,227,227, 227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, 227,227, 92,227,227,227,227,227,227,227,227,227, 92,227, 92, 92, 227,227,227,227,227,227,227, 92, 92, 92,228, 92, 92, 92, 92,226, 226,226,228,228,228, 92,228, 92,226,226,226,226,226,226,226,226, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,226,226,229, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 28 */ 92,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, 230,231,230,230,231,231,231,231,231,231,231, 92, 92, 92, 92, 3, 230,230,230,230,230,230,232,231,231,231,231,231,231,231,231,233, 234,234,234,234,234,234,234,234,234,234,233,233, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 29 */ 92,235,235, 92,235, 92, 92,235,235, 92,235, 92, 92,235, 92, 92, 92, 92, 92, 92,235,235,235,235, 92,235,235,235,235,235,235,235, 92,235,235,235, 92,235, 92,235, 92, 92,235,235, 92,235,235,235, 235,236,235,235,236,236,236,236,236,236, 92,236,236,235, 92, 92, 235,235,235,235,235, 92,237, 92,236,236,236,236,236,236, 92, 92, 238,238,238,238,238,238,238,238,238,238, 92, 92,235,235,235,235, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 30 */ 239,240,240,240,241,241,241,241,241,241,241,241,241,241,241,241, 241,241,241,240,241,240,240,240,242,242,240,240,240,240,240,240, 243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244, 244,244,244,244,240,242,240,242,240,242,245,246,245,246,247,247, 239,239,239,239,239,239,239,239, 92,239,239,239,239,239,239,239, 239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, 239,239,239,239,239,239,239,239,239,239,239,239,239, 92, 92, 92, 92,242,242,242,242,242,242,242,242,242,242,242,242,242,242,247, /* block 31 */ 242,242,242,242,242,241,242,242,239,239,239,239,239,242,242,242, 242,242,242,242,242,242,242,242, 92,242,242,242,242,242,242,242, 242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, 242,242,242,242,242,242,242,242,242,242,242,242,242, 92,240,240, 240,240,240,240,240,240,242,240,240,240,240,240,240, 92,240,240, 241,241,241,241,241, 13, 13, 13, 13,241,241, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 32 */ 248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, 248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, 248,248,248,248,248,248,248,248,248,248,248,249,249,250,250,250, 250,249,250,250,250,250,250,250,249,250,250,249,249,250,250,248, 251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252, 248,248,248,248,248,248,249,249,250,250,248,248,248,248,250,250, 250,248,249,249,249,248,248,249,249,249,249,249,249,249,248,248, 248,250,250,250,250,248,248,248,248,248,248,248,248,248,248,248, /* block 33 */ 248,248,250,249,249,250,250,249,249,249,249,249,249,250,248,249, 251,251,251,251,251,251,251,251,251,251,249,249,249,250,253,253, 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, 254,254,254,254,254,254, 92,254, 92, 92, 92, 92, 92,254, 92, 92, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255, 2,256,255,255,255, /* block 34 */ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, /* block 35 */ 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92, 258,258,258,258,258,258,258, 92,258, 92,258,258,258,258, 92, 92, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, /* block 36 */ 258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258, 92, 258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, /* block 37 */ 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258,258,258,258,258, 92, 92,259,259,259, 260,260,260,260,260,260,260,260,260,261,261,261,261,261,261,261, 261,261,261,261,261,261,261,261,261,261,261,261,261, 92, 92, 92, /* block 38 */ 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 262,262,262,262,262,262,262,262,262,262, 92, 92, 92, 92, 92, 92, 263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, 263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, 263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, 263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, 263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, 263,263,263,263,263, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 39 */ 264,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 40 */ 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 41 */ 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,266,266,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 42 */ 267,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268, 268,268,268,268,268,268,268,268,268,268,268,269,270, 92, 92, 92, 271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, 271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, 271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, 271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, 271,271,271,271,271,271,271,271,271,271,271, 2, 2, 2,272,272, 272, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 43 */ 273,273,273,273,273,273,273,273,273,273,273,273,273, 92,273,273, 273,273,274,274,274, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275, 275,275,276,276,276, 2, 2, 92, 92, 92, 92, 92, 92, 92, 92, 92, 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, 277,277,278,278, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 279,279,279,279,279,279,279,279,279,279,279,279,279, 92,279,279, 279, 92,280,280, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 44 */ 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, 281,281,281,281,282,282,283,282,282,282,282,282,282,282,283,283, 283,283,283,283,283,283,282,283,283,282,282,282,282,282,282,282, 282,282,282,282,284,284,284,285,284,284,284,286,281,282, 92, 92, 287,287,287,287,287,287,287,287,287,287, 92, 92, 92, 92, 92, 92, 288,288,288,288,288,288,288,288,288,288, 92, 92, 92, 92, 92, 92, /* block 45 */ 289,289, 2, 2,289, 2,290,289,289,289,289,291,291,291,292, 92, 293,293,293,293,293,293,293,293,293,293, 92, 92, 92, 92, 92, 92, 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, 294,294,294,295,294,294,294,294,294,294,294,294,294,294,294,294, 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, 294,294,294,294,294,294,294,294, 92, 92, 92, 92, 92, 92, 92, 92, /* block 46 */ 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, 294,294,294,294,294,294,294,294,294,291,294, 92, 92, 92, 92, 92, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, 265,265,265,265,265,265, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 47 */ 296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, 296,296,296,296,296,296,296,296,296,296,296,296,296, 92, 92, 92, 297,297,297,298,298,298,298,297,297,298,298,298, 92, 92, 92, 92, 298,298,297,298,298,298,298,298,298,297,297,297, 92, 92, 92, 92, 299, 92, 92, 92,300,300,301,301,301,301,301,301,301,301,301,301, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302, 92, 92, 302,302,302,302,302, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 48 */ 303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, 303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, 303,303,303,303,303,303,303,303,303,303,303,303, 92, 92, 92, 92, 304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304, 304,303,303,303,303,303,303,303,304,304, 92, 92, 92, 92, 92, 92, 305,305,305,305,305,305,305,305,305,305,306, 92, 92, 92,307,307, 308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, 308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, /* block 49 */ 309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309, 309,309,309,309,309,309,309,310,310,311,311,311, 92, 92,312,312, 313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, 313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, 313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, 313,313,313,313,313,314,315,314,315,315,315,315,315,315,315, 92, 315,314,315,314,314,315,315,315,315,315,315,315,315,314,314,314, 314,314,314,315,315,315,315,315,315,315,315,315,315, 92, 92,315, /* block 50 */ 316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92, 316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92, 317,317,317,317,317,317,317,318,317,317,317,317,317,317, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 51 */ 319,319,319,319,320,321,321,321,321,321,321,321,321,321,321,321, 321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, 321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, 321,321,321,321,319,320,319,319,319,319,319,320,319,320,320,320, 320,320,319,320,320,321,321,321,321,321,321,321, 92, 92, 92, 92, 322,322,322,322,322,322,322,322,322,322,323,323,323,323,323,323, 323,324,324,324,324,324,324,324,324,324,324,319,319,319,319,319, 319,319,319,319,324,324,324,324,324,324,324,324,324, 92, 92, 92, /* block 52 */ 325,325,326,327,327,327,327,327,327,327,327,327,327,327,327,327, 327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327, 327,326,325,325,325,325,326,326,325,325,326,325,326,326,327,327, 328,328,328,328,328,328,328,328,328,328,327,327,327,327,327,327, 329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329, 329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329, 329,329,329,329,329,329,330,331,330,330,331,331,331,330,331,330, 330,330,331,331, 92, 92, 92, 92, 92, 92, 92, 92,332,332,332,332, /* block 53 */ 333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333, 333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333, 333,333,333,333,334,334,334,334,334,334,334,334,335,335,335,335, 335,335,335,335,334,334,335,335, 92, 92, 92,336,336,336,336,336, 337,337,337,337,337,337,337,337,337,337, 92, 92, 92,333,333,333, 338,338,338,338,338,338,338,338,338,338,339,339,339,339,339,339, 339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339, 339,339,339,339,339,339,339,339,340,340,340,340,340,340,341,341, /* block 54 */ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 342,342,342,342,342,342,342,342, 92, 92, 92, 92, 92, 92, 92, 92, 87, 87, 87, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,343, 87, 87, 87, 87, 87, 87, 87,344,344,344,344, 87,344,344, 344,344,343,343, 87,344,344, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 55 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 99, 99, 99, 99, 99,345, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93, 93, 93, 93, 93, 84, 84, 84, 84, 93, 93, 93, 93, 93, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,346,347, 20, 20, 20,348, 20, 20, /* block 56 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 87, 87, 87, 87, /* block 57 */ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, /* block 58 */ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 20, 20, 20, 20,349, 20, 20,350, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, /* block 59 */ 351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, 351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92, 351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, 351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, 351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92, 99,351, 99,351, 99,351, 99,351, 92,352, 92,352, 92,352, 92,352, 351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, 353,353,354,354,354,354,355,355,356,356,357,357,358,358, 92, 92, /* block 60 */ 351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, 351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, 351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, 351,351, 99,360, 99, 92, 99, 99,352,352,361,361,362, 91,363, 91, 91, 91, 99,360, 99, 92, 99, 99,364,364,364,364,362, 91, 91, 91, 351,351, 99, 99, 92, 92, 99, 99,352,352,365,365, 92, 91, 91, 91, 351,351, 99, 99, 99,118, 99, 99,352,352,366,366,122, 91, 91, 91, 92, 92, 99,360, 99, 92, 99, 99,367,367,368,368,362, 91, 91, 92, /* block 61 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,369,369, 16, 16, 7, 7, 7, 7, 7, 7, 2, 2, 15, 19, 4, 15, 15, 19, 4, 15, 2, 2, 2, 2, 2, 2, 2, 2,370,371, 16, 16, 16, 16, 16, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 19, 2, 2, 2, 2, 11, 11, 2, 2, 2, 6, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 16, 16, 16, 16, 16, 92, 92, 92, 92, 92, 16, 16, 16, 16, 16, 16, 17, 84, 92, 92, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 84, /* block 62 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 92, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,372,372,372, 372, 87,372,372,372, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 63 */ 13, 13,373, 13, 13, 13, 13,373, 13, 13,374,373,373,373,374,374, 373,373,373,374, 13,373, 13, 13, 6,373,373,373,373,373, 13, 13, 13, 13, 13, 13,373, 13,375, 13,373, 13,376,377,373,373, 13,374, 373,373,378,373,374,344,344,344,344,374, 13, 13,374,374,373,373, 6, 6, 6, 6, 6,373,374,374,374,374, 13, 6, 13, 13,379, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, 381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, /* block 64 */ 382,382,382, 22, 23,382,382,382,382, 17, 92, 92, 92, 92, 92, 92, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13, 6, 13, 13, 6, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 13, 13, 6, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, /* block 65 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, /* block 66 */ 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13, 13, 13, 13, 4, 5, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, /* block 67 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 68 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* block 69 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,383,383,383,383,383,383,383,383,383,383, 383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, 384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, 384,384,384,384,384,384,384,384,384,384, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* block 70 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 71 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, /* block 72 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 73 */ 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* block 74 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, /* block 75 */ 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, /* block 76 */ 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6, /* block 77 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 78 */ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 79 */ 386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, 386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, 386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, 92, 387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, 387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, 387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, 92, 22, 23,388,389,390,391,392, 22, 23, 22, 23, 22, 23,393,394,395, 396, 20, 22, 23, 20, 22, 23, 20, 20, 20, 20, 20, 84, 84,397,397, /* block 80 */ 114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, 114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, 114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, 114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, 114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, 114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, 114,115,114,115,398,399,399,399,399,399,399,114,115,114,115,400, 400,400,114,115, 92, 92, 92, 92, 92,401,401,401,401,402,401,401, /* block 81 */ 403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, 403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, 403,403,403,403,403,403, 92,403, 92, 92, 92, 92, 92,403, 92, 92, 404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, 404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, 404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, 404,404,404,404,404,404,404,404, 92, 92, 92, 92, 92, 92, 92,405, 406, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,407, /* block 82 */ 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, 258,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92, 258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, 258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, 258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, 258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, /* block 83 */ 2, 2, 15, 19, 15, 19, 2, 2, 2, 15, 19, 2, 15, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 7, 2, 15, 19, 2, 2, 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 84 */ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408, 92,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 85 */ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, /* block 86 */ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, 408,408,408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, /* block 87 */ 1, 2, 2, 2, 13,409,344,410, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 7, 4, 5, 5, 13,410,410,410,410,410,410,410,410,410, 87, 87, 87, 87,411,411, 7, 85, 85, 85, 85, 85, 13, 13,410,410,410,409,344, 2, 13, 13, 92,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, /* block 88 */ 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,412,412,412,412,412, 92, 92, 87, 87, 10, 10,413,413,412, 7,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 414,414,414,414,414,414,414,414,414,414,414, 2, 85,415,415,414, /* block 89 */ 92, 92, 92, 92, 92,416,416,416,416,416,416,416,416,416,416,416, 416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, 416,416,416,416,416,416,416,416,416,416,416,416,416,416, 92, 92, 92,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, /* block 90 */ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 13, 13, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, 416,416,416,416,416,416,416,416,416,416,416, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, /* block 91 */ 417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 13, /* block 92 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 92, /* block 93 */ 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 418,418,418,418,418,418,418,418, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 94 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, /* block 95 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 96 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 97 */ 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,421,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, /* block 98 */ 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, 420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, /* block 99 */ 420,420,420,420,420,420,420,420,420,420,420,420,420, 92, 92, 92, 422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, 422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, 422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, 422,422,422,422,422,422,422, 92, 92, 92, 92, 92, 92, 92, 92, 92, 423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, 423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, 423,423,423,423,423,423,423,423,424,424,424,424,424,424,425,425, /* block 100 */ 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, /* block 101 */ 426,426,426,426,426,426,426,426,426,426,426,426,427,428,428,428, 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, 429,429,429,429,429,429,429,429,429,429,426,426, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129,128,129,128,129,128,129,430,131, 132,132,132,431,131,131,131,131,131,131,131,131,131,131,431,346, /* block 102 */ 128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, 128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92,131, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,433,433,433,433,433,433,433,433,433,433, 434,434,435,435,435,435,435,435, 92, 92, 92, 92, 92, 92, 92, 92, /* block 103 */ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85, 10, 10, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 84, 20, 20, 20, 20, 20, 20, 20, 20, 22, 23, 22, 23,436, 22, 23, /* block 104 */ 22, 23, 22, 23, 22, 23, 22, 23, 85, 10, 10, 22, 23,437, 20, 92, 22, 23, 22, 23, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,438, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 84, 84, 20, 14, 14, 14, 14, 14, /* block 105 */ 439,439,440,439,439,439,440,439,439,439,439,440,439,439,439,439, 439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439, 439,439,439,441,441,440,440,441,442,442,442,442, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 92, 92, 92, 92, 92, 92, 443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, 443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, 443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, 443,443,443,443,444,444,444,444, 92, 92, 92, 92, 92, 92, 92, 92, /* block 106 */ 445,445,446,446,446,446,446,446,446,446,446,446,446,446,446,446, 446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, 446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, 446,446,446,446,445,445,445,445,445,445,445,445,445,445,445,445, 445,445,445,445,447, 92, 92, 92, 92, 92, 92, 92, 92, 92,448,448, 449,449,449,449,449,449,449,449,449,449, 92, 92, 92, 92, 92, 92, 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, 174,174,176,176,176,176,176,176,178,178,178,176, 92, 92, 92, 92, /* block 107 */ 450,450,450,450,450,450,450,450,450,450,451,451,451,451,451,451, 451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, 451,451,451,451,451,451,452,452,452,452,452,452,452,452,453,453, 454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454, 454,454,454,454,454,454,454,455,455,455,455,455,455,455,455,455, 455,455,456,456, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,457, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92, /* block 108 */ 458,458,458,459,460,460,460,460,460,460,460,460,460,460,460,460, 460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, 460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, 460,460,460,458,459,459,458,458,458,458,459,459,458,459,459,459, 459,461,461,461,461,461,461,461,461,461,461,461,461,461, 92,462, 463,463,463,463,463,463,463,463,463,463, 92, 92, 92, 92,461,461, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 109 */ 464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, 464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, 464,464,464,464,464,464,464,464,464,465,465,465,465,465,465,466, 466,465,465,466,466,465,465, 92, 92, 92, 92, 92, 92, 92, 92, 92, 464,464,464,465,464,464,464,464,464,464,464,464,465,466, 92, 92, 467,467,467,467,467,467,467,467,467,467, 92, 92,468,468,468,468, 248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, 469,248,248,248,248,248,248,253,253,253,248,249, 92, 92, 92, 92, /* block 110 */ 470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, 470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, 470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, 471,470,471,471,471,470,470,471,471,470,470,470,470,470,471,471, 470,471,470, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,470,470,472,473,473, 474,474,474,474,474,474,474,474,474,474,474,475,476,476,475,475, 477,477,474,478,478,475,476, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 111 */ 92,258,258,258,258,258,258, 92, 92,258,258,258,258,258,258, 92, 92,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92, 258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 112 */ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, 474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, 474,474,474,475,475,476,475,475,476,475,475,477,475,476, 92, 92, 479,479,479,479,479,479,479,479,479,479, 92, 92, 92, 92, 92, 92, /* block 113 */ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257, 92, 92, 92, 92,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92, 92, /* block 114 */ 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, 480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, /* block 115 */ 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, /* block 116 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, /* block 117 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 118 */ 20, 20, 20, 20, 20, 20, 20, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,139,139,139,139,139, 92, 92, 92, 92, 92,145,142,145, 145,145,145,145,145,145,145,145,145,482,145,145,145,145,145,145, 145,145,145,145,145,145,145, 92,145,145,145,145,145, 92,145, 92, 145,145, 92,145,145, 92,145,145,145,145,145,145,145,145,145,145, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 119 */ 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,483,483,483,483,483,483,483,483,483,483,483,483,483,483, 483,483, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 120 */ 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 121 */ 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152, 4, 5, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 122 */ 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 152,152,152,152,152,152,152,152,152,152,152,152,149, 13, 92, 92, /* block 123 */ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 92, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11, 2, 2, 2, 92, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2, 2, 2, 6, 7, 6, 6, 6, 92, 2, 3, 2, 2, 92, 92, 92, 92, 152,152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152, /* block 124 */ 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 16, /* block 125 */ 92, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 4, 5, 2, 4, 5, 2, 2,414,414,414,414,414,414,414,414,414,414, 85,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, /* block 126 */ 414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 414,414,414,414,414,414,414,414,414,414,414,414,414,414, 85, 85, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92,257,257,257,257,257,257, 92, 92,257,257,257,257,257,257, 92, 92,257,257,257,257,257,257, 92, 92,257,257,257, 92, 92, 92, 3, 3, 6, 10, 13, 3, 3, 92, 13, 6, 6, 6, 6, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 16, 16, 16, 13, 13, 92, 92, /* block 127 */ 484,484,484,484,484,484,484,484,484,484,484,484, 92,484,484,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484, 92,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484, 92,484,484, 92,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92, 484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 128 */ 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,484,484,484,484,484,484,484,484, 92, 92, 92, 92, 92, /* block 129 */ 2, 2, 2, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, 485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, 485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, 485,485,485,485,485,486,486,486,486,487,487,487,487,487,487,487, /* block 130 */ 487,487,487,487,487,487,487,487,487,487,486, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 92, 92, /* block 131 */ 488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488, 488,488,488,488,488,488,488,488,488,488,488,488,488, 92, 92, 92, 489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, 489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, 489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, 489, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 132 */ 490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, 490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, 92, 491,491,491,491, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, 492,493,492,492,492,492,492,492,492,492,493, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 133 */ 494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494, 494,494,494,494,494,494,494,494,494,494,494,494,494,494, 92,495, 496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, 496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, 496,496,496,496, 92, 92, 92, 92,496,496,496,496,496,496,496,496, 497,498,498,498,498,498, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 134 */ 499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, 499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, 499,499,499,499,499,499,499,499,500,500,500,500,500,500,500,500, 500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, 500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, 501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, 501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, 501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, /* block 135 */ 502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, 502,502,502,502,502,502,502,502,502,502,502,502,502,502, 92, 92, 503,503,503,503,503,503,503,503,503,503, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 136 */ 504,504,504,504,504,504, 92, 92,504, 92,504,504,504,504,504,504, 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, 504,504,504,504,504,504, 92,504,504, 92, 92, 92,504, 92, 92,504, 505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, 505,505,505,505,505,505, 92,506,507,507,507,507,507,507,507,507, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 137 */ 508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508, 508,508,508,508,508,508,509,509,509,509,509,509, 92, 92, 92,510, 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, 511,511,511,511,511,511,511,511,511,511, 92, 92, 92, 92, 92,512, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 138 */ 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 514,514,514,514,514,514,514,514, 92, 92, 92, 92, 92, 92,514,514, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 139 */ 515,516,516,516, 92,516,516, 92, 92, 92, 92, 92,516,516,516,516, 515,515,515,515, 92,515,515,515, 92,515,515,515,515,515,515,515, 515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, 515,515,515,515, 92, 92, 92, 92,516,516,516, 92, 92, 92, 92,516, 517,517,517,517,517,517,517,517, 92, 92, 92, 92, 92, 92, 92, 92, 518,518,518,518,518,518,518,518,518, 92, 92, 92, 92, 92, 92, 92, 519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, 519,519,519,519,519,519,519,519,519,519,519,519,519,520,520,521, /* block 140 */ 522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, 522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, 522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, 522,522,522,522,522,522, 92, 92, 92,523,523,523,523,523,523,523, 524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, 524,524,524,524,524,524, 92, 92,525,525,525,525,525,525,525,525, 526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, 526,526,526, 92, 92, 92, 92, 92,527,527,527,527,527,527,527,527, /* block 141 */ 528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, 528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, 528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, 528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, 528,528,528,528,528,528,528,528,528, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 142 */ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, 529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, 92, /* block 143 */ 530,531,530,532,532,532,532,532,532,532,532,532,532,532,532,532, 532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, 532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, 532,532,532,532,532,532,532,532,531,531,531,531,531,531,531,531, 531,531,531,531,531,531,531,533,533,533,533,533,533,533, 92, 92, 92, 92,534,534,534,534,534,534,534,534,534,534,534,534,534,534, 534,534,534,534,534,534,535,535,535,535,535,535,535,535,535,535, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 144 */ 536,536,537,538,538,538,538,538,538,538,538,538,538,538,538,538, 538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, 538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, 537,537,537,536,536,536,536,537,537,536,536,539,539,540,539,539, 539,539, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, 541,541,541,541,541,541,541,541,541, 92, 92, 92, 92, 92, 92, 92, 542,542,542,542,542,542,542,542,542,542, 92, 92, 92, 92, 92, 92, /* block 145 */ 543,543,543,544,544,544,544,544,544,544,544,544,544,544,544,544, 544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, 544,544,544,544,544,544,544,543,543,543,543,543,545,543,543,543, 543,543,543,543,543, 92,546,546,546,546,546,546,546,546,546,546, 547,547,547,547, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 146 */ 548,548,549,550,550,550,550,550,550,550,550,550,550,550,550,550, 550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550, 550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550, 550,550,550,549,549,549,548,548,548,548,548,548,548,548,548,549, 549,550,550,550,550,551,551,551,551, 92, 92, 92, 92, 92, 92, 92, 552,552,552,552,552,552,552,552,552,552, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 147 */ 553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, 553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, 553,553,553,553,553,553,553,553,553,553,553,554,555,554,555,555, 554,554,554,554,554,554,555,554, 92, 92, 92, 92, 92, 92, 92, 92, 556,556,556,556,556,556,556,556,556,556, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 148 */ 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, /* block 149 */ 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 150 */ 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, 558,558,558, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 559,559,559,559, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 151 */ 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, /* block 152 */ 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 153 */ 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, /* block 154 */ 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, 432,432,432,432,432,432,432,432,432, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 155 */ 561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, 561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, 561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, 561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, 561,561,561,561,561, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 561,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, 562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, 562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, 92, /* block 156 */ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,563, 563,563,563,564,564,564,564,564,564,564,564,564,564,564,564,564, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 157 */ 414,412, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 158 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 159 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,343,343, 87, 87, 87, 13, 13, 13,343,343,343, 343,343,343, 16, 16, 16, 16, 16, 16, 16, 16, 87, 87, 87, 87, 87, /* block 160 */ 87, 87, 87, 13, 13, 87, 87, 87, 87, 87, 87, 87, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 87, 87, 87, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 161 */ 487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, 487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, 487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, 487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, 487,487,565,565,565,487, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 162 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 163 */ 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374, 374,374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, /* block 164 */ 373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,373, 92,373,373, 92, 92,373, 92, 92,373,373, 92, 92,373,373,373,373, 92,373,373, 373,373,373,373,373,373,374,374,374,374, 92,374, 92,374,374,374, 374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374,374, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, /* block 165 */ 374,374,374,374,373,373, 92,373,373,373,373, 92, 92,373,373,373, 373,373,373,373,373, 92,373,373,373,373,373,373,373, 92,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,373,373, 92,373,373,373,373, 92, 373,373,373,373,373, 92,373, 92, 92, 92,373,373,373,373,373,373, 373, 92,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, /* block 166 */ 373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, /* block 167 */ 374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, /* block 168 */ 373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374, 92, 92,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373, 6,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374, 6,374,374,374,374, 374,374,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373, 6,374,374,374,374, /* block 169 */ 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374, 6,374,374,374,374,374,374,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373, 6,374,374,374,374,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 6, 374,374,374,374,374,374,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 6, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, /* block 170 */ 374,374,374,374,374,374,374,374,374, 6,374,374,374,374,374,374, 373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 373,373,373,373,373,373,373,373,373, 6,374,374,374,374,374,374, 374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 374,374,374, 6,374,374,374,374,374,374,373,374, 92, 92, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* block 171 */ 152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 92,152,152, 92,152, 92, 92,152, 92,152,152,152,152,152,152,152, 152,152,152, 92,152,152,152,152, 92,152, 92,152, 92, 92, 92, 92, 92, 92,152, 92, 92, 92, 92,152, 92,152, 92,152, 92,152,152,152, 92,152,152, 92,152, 92, 92,152, 92,152, 92,152, 92,152, 92,152, 92,152,152, 92,152, 92, 92,152,152,152,152, 92,152,152,152,152, 152,152,152, 92,152,152,152,152, 92,152,152,152,152, 92,152, 92, /* block 172 */ 152,152,152,152,152,152,152,152,152,152, 92,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92, 92,152,152,152, 92,152,152,152,152,152, 92,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 147,147, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 173 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 174 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 175 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 176 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 177 */ 566, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 178 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, /* block 179 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 180 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 181 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 92, 92, 92, /* block 182 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 183 */ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, /* block 184 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 185 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 186 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 187 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 188 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, /* block 189 */ 419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, 419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 190 */ 92, 16, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, /* block 191 */ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, /* block 192 */ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 193 */ 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,481,481, 92, 92, }; #if UCD_BLOCK_SIZE != 128 #error Please correct UCD_BLOCK_SIZE in pcre_internal.h #endif #endif /* SUPPORT_UCP */ pcre-8.31/sljit/0000755000222100022210000000000011775533032010516 500000000000000pcre-8.31/sljit/sljitUtils.c0000644000222100022210000001722411731100452012742 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* ------------------------------------------------------------------------ */ /* Locks */ /* ------------------------------------------------------------------------ */ #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) static SLJIT_INLINE void allocator_grab_lock(void) { /* Always successful. */ } static SLJIT_INLINE void allocator_release_lock(void) { /* Always successful. */ } #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) { /* Always successful. */ } SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) { /* Always successful. */ } #endif /* SLJIT_UTIL_GLOBAL_LOCK */ #elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */ #include "windows.h" #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) static HANDLE allocator_mutex = 0; static SLJIT_INLINE void allocator_grab_lock(void) { /* No idea what to do if an error occures. Static mutexes should never fail... */ if (!allocator_mutex) allocator_mutex = CreateMutex(NULL, TRUE, NULL); else WaitForSingleObject(allocator_mutex, INFINITE); } static SLJIT_INLINE void allocator_release_lock(void) { ReleaseMutex(allocator_mutex); } #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) static HANDLE global_mutex = 0; SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) { /* No idea what to do if an error occures. Static mutexes should never fail... */ if (!global_mutex) global_mutex = CreateMutex(NULL, TRUE, NULL); else WaitForSingleObject(global_mutex, INFINITE); } SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) { ReleaseMutex(global_mutex); } #endif /* SLJIT_UTIL_GLOBAL_LOCK */ #else /* _WIN32 */ #include "pthread.h" #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER; static SLJIT_INLINE void allocator_grab_lock(void) { pthread_mutex_lock(&allocator_mutex); } static SLJIT_INLINE void allocator_release_lock(void) { pthread_mutex_unlock(&allocator_mutex); } #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) { pthread_mutex_lock(&global_mutex); } SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) { pthread_mutex_unlock(&global_mutex); } #endif /* SLJIT_UTIL_GLOBAL_LOCK */ #endif /* _WIN32 */ /* ------------------------------------------------------------------------ */ /* Stack */ /* ------------------------------------------------------------------------ */ #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) #ifdef _WIN32 #include "windows.h" #else #include #include #endif /* Planning to make it even more clever in the future. */ static sljit_w sljit_page_align = 0; SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit) { struct sljit_stack *stack; union { void *ptr; sljit_uw uw; } base; #ifdef _WIN32 SYSTEM_INFO si; #endif if (limit > max_limit || limit < 1) return NULL; #ifdef _WIN32 if (!sljit_page_align) { GetSystemInfo(&si); sljit_page_align = si.dwPageSize - 1; } #else if (!sljit_page_align) { sljit_page_align = sysconf(_SC_PAGESIZE); /* Should never happen. */ if (sljit_page_align < 0) sljit_page_align = 4096; sljit_page_align--; } #endif /* Align limit and max_limit. */ max_limit = (max_limit + sljit_page_align) & ~sljit_page_align; stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack)); if (!stack) return NULL; #ifdef _WIN32 base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE); if (!base.ptr) { SLJIT_FREE(stack); return NULL; } stack->base = base.uw; stack->limit = stack->base; stack->max_limit = stack->base + max_limit; if (sljit_stack_resize(stack, stack->base + limit)) { sljit_free_stack(stack); return NULL; } #else base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (base.ptr == MAP_FAILED) { SLJIT_FREE(stack); return NULL; } stack->base = base.uw; stack->limit = stack->base + limit; stack->max_limit = stack->base + max_limit; #endif stack->top = stack->base; return stack; } #undef PAGE_ALIGN SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack) { #ifdef _WIN32 VirtualFree((void*)stack->base, 0, MEM_RELEASE); #else munmap((void*)stack->base, stack->max_limit - stack->base); #endif SLJIT_FREE(stack); } SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit) { sljit_uw aligned_old_limit; sljit_uw aligned_new_limit; if ((new_limit > stack->max_limit) || (new_limit < stack->base)) return -1; #ifdef _WIN32 aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; if (aligned_new_limit != aligned_old_limit) { if (aligned_new_limit > aligned_old_limit) { if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE)) return -1; } else { if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT)) return -1; } } stack->limit = new_limit; return 0; #else if (new_limit >= stack->limit) { stack->limit = new_limit; return 0; } aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; if (aligned_new_limit < aligned_old_limit) posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); stack->limit = new_limit; return 0; #endif } #endif /* SLJIT_UTIL_STACK */ #endif pcre-8.31/sljit/sljitNativePPC_32.c0000644000222100022210000002315511703042632013743 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* ppc 32-bit arch dependent functions. */ static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm) { if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); if (!(imm & ~0xffff)) return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm)); FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; } #define INS_CLEAR_LEFT(dst, src, from) \ (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1)) static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, int dst, int src1, int src2) { switch (op) { case SLJIT_ADD: if (flags & ALT_FORM1) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); } if (flags & ALT_FORM2) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); } if (flags & ALT_FORM3) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); } if (flags & ALT_FORM4) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); } if (!(flags & ALT_SET_FLAGS)) return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); case SLJIT_ADDC: if (flags & ALT_FORM1) { FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); return push_inst(compiler, MTXER | S(0)); } return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); case SLJIT_SUB: if (flags & ALT_FORM1) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); } if (flags & (ALT_FORM2 | ALT_FORM3)) { SLJIT_ASSERT(src2 == TMP_REG2); if (flags & ALT_FORM2) FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm)); if (flags & ALT_FORM3) return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm); return SLJIT_SUCCESS; } if (flags & (ALT_FORM4 | ALT_FORM5)) { if (flags & ALT_FORM4) FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); if (flags & ALT_FORM5) FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2))); return SLJIT_SUCCESS; } if (!(flags & ALT_SET_FLAGS)) return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); if (flags & ALT_FORM6) FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); case SLJIT_SUBC: if (flags & ALT_FORM1) { FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); return push_inst(compiler, MTXER | S(0)); } return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); case SLJIT_MUL: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); } return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); case SLJIT_AND: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM2) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); } return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_OR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM2) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM3) { SLJIT_ASSERT(src2 == TMP_REG2); FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); } return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_XOR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM2) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM3) { SLJIT_ASSERT(src2 == TMP_REG2); FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); } return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_SHL: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); compiler->imm &= 0x1f; return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); } return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_LSHR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); compiler->imm &= 0x1f; return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); } return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_ASHR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); compiler->imm &= 0x1f; return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)); } return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: SLJIT_ASSERT(src1 == TMP_REG1); if (dst != src2) return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); return SLJIT_SUCCESS; case SLJIT_MOV_UB: case SLJIT_MOV_SB: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_SB) return push_inst(compiler, EXTSB | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); } else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) return push_inst(compiler, EXTSB | S(src2) | A(dst)); else if (dst != src2) SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; case SLJIT_MOV_UH: case SLJIT_MOV_SH: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_SH) return push_inst(compiler, EXTSH | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); } else if (dst != src2) SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; case SLJIT_NOT: SLJIT_ASSERT(src1 == TMP_REG1); return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); case SLJIT_NEG: SLJIT_ASSERT(src1 == TMP_REG1); return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1); return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16))); return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { sljit_ins *inst = (sljit_ins*)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); SLJIT_CACHE_FLUSH(inst, inst + 2); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_ins *inst = (sljit_ins*)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); SLJIT_CACHE_FLUSH(inst, inst + 2); } pcre-8.31/sljit/sljitNativePPC_64.c0000644000222100022210000003620111703042632013744 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* ppc 64-bit arch dependent functions. */ #ifdef __GNUC__ #define ASM_SLJIT_CLZ(src, dst) \ asm volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) ) #else #error "Must implement count leading zeroes" #endif #define RLDI(dst, src, sh, mb, type) \ (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) #define PUSH_RLDICR(reg, shift) \ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm) { sljit_uw tmp; sljit_uw shift; sljit_uw tmp2; sljit_uw shift2; if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); if (!(imm & ~0xffff)) return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm)); if (imm <= SLJIT_W(0x7fffffff) && imm >= SLJIT_W(-0x80000000)) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; } /* Count leading zeroes. */ tmp = (imm >= 0) ? imm : ~imm; ASM_SLJIT_CLZ(tmp, shift); SLJIT_ASSERT(shift > 0); shift--; tmp = (imm << shift); if ((tmp & ~0xffff000000000000ul) == 0) { FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); shift += 15; return PUSH_RLDICR(reg, shift); } if ((tmp & ~0xffffffff00000000ul) == 0) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48))); FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32))); shift += 31; return PUSH_RLDICR(reg, shift); } /* Cut out the 16 bit from immediate. */ shift += 15; tmp2 = imm & ((1ul << (63 - shift)) - 1); if (tmp2 <= 0xffff) { FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); FAIL_IF(PUSH_RLDICR(reg, shift)); return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2); } if (tmp2 <= 0xffffffff) { FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); FAIL_IF(PUSH_RLDICR(reg, shift)); FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16))); return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS; } ASM_SLJIT_CLZ(tmp2, shift2); tmp2 <<= shift2; if ((tmp2 & ~0xffff000000000000ul) == 0) { FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); shift2 += 15; shift += (63 - shift2); FAIL_IF(PUSH_RLDICR(reg, shift)); FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48))); return PUSH_RLDICR(reg, shift2); } /* The general version. */ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48))); FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32))); FAIL_IF(PUSH_RLDICR(reg, 31)); FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16))); return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)); } /* Simplified mnemonics: clrldi. */ #define INS_CLEAR_LEFT(dst, src, from) \ (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5)) /* Sign extension for integer operations. */ #define UN_EXTS() \ if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ src2 = TMP_REG2; \ } #define BIN_EXTS() \ if (flags & ALT_SIGN_EXT) { \ if (flags & REG1_SOURCE) { \ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ src1 = TMP_REG1; \ } \ if (flags & REG2_SOURCE) { \ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ src2 = TMP_REG2; \ } \ } #define BIN_IMM_EXTS() \ if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ src1 = TMP_REG1; \ } static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, int dst, int src1, int src2) { switch (op) { case SLJIT_ADD: if (flags & ALT_FORM1) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); } if (flags & ALT_FORM2) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); } if (flags & ALT_FORM3) { SLJIT_ASSERT(src2 == TMP_REG2); BIN_IMM_EXTS(); return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); } if (flags & ALT_FORM4) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); } if (!(flags & ALT_SET_FLAGS)) return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); BIN_EXTS(); return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); case SLJIT_ADDC: if (flags & ALT_FORM1) { FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); return push_inst(compiler, MTXER | S(0)); } BIN_EXTS(); return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); case SLJIT_SUB: if (flags & ALT_FORM1) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); } if (flags & (ALT_FORM2 | ALT_FORM3)) { SLJIT_ASSERT(src2 == TMP_REG2); if (flags & ALT_FORM2) FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm)); if (flags & ALT_FORM3) return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm); return SLJIT_SUCCESS; } if (flags & (ALT_FORM4 | ALT_FORM5)) { if (flags & ALT_FORM4) FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); if (flags & ALT_FORM5) return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)); return SLJIT_SUCCESS; } if (!(flags & ALT_SET_FLAGS)) return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); BIN_EXTS(); if (flags & ALT_FORM6) FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); case SLJIT_SUBC: if (flags & ALT_FORM1) { FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); return push_inst(compiler, MTXER | S(0)); } BIN_EXTS(); return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); case SLJIT_MUL: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); } BIN_EXTS(); if (flags & ALT_FORM2) return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1)); case SLJIT_AND: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM2) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); } return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_OR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM2) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM3) { SLJIT_ASSERT(src2 == TMP_REG2); FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); } return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_XOR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM2) { SLJIT_ASSERT(src2 == TMP_REG2); return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); } if (flags & ALT_FORM3) { SLJIT_ASSERT(src2 == TMP_REG2); FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); } return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_SHL: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); if (flags & ALT_FORM2) { compiler->imm &= 0x1f; return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); } else { compiler->imm &= 0x3f; return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags)); } } if (flags & ALT_FORM2) return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2)); return push_inst(compiler, SLD | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_LSHR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); if (flags & ALT_FORM2) { compiler->imm &= 0x1f; return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); } else { compiler->imm &= 0x3f; return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags)); } } if (flags & ALT_FORM2) return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); return push_inst(compiler, SRD | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_ASHR: if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); if (flags & ALT_FORM2) { compiler->imm &= 0x1f; return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)); } else { compiler->imm &= 0x3f; return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4)); } } if (flags & ALT_FORM2) return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)); return push_inst(compiler, SRAD | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_MOV: SLJIT_ASSERT(src1 == TMP_REG1); if (dst != src2) return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); return SLJIT_SUCCESS; case SLJIT_MOV_UI: case SLJIT_MOV_SI: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_SI) return push_inst(compiler, EXTSW | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); } else if (dst != src2) SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; case SLJIT_MOV_UB: case SLJIT_MOV_SB: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_SB) return push_inst(compiler, EXTSB | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); } else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) return push_inst(compiler, EXTSB | S(src2) | A(dst)); else if (dst != src2) SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; case SLJIT_MOV_UH: case SLJIT_MOV_SH: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_SH) return push_inst(compiler, EXTSH | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); } else if (dst != src2) SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; case SLJIT_NOT: SLJIT_ASSERT(src1 == TMP_REG1); UN_EXTS(); return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); case SLJIT_NEG: SLJIT_ASSERT(src1 == TMP_REG1); UN_EXTS(); return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1); if (flags & ALT_FORM1) return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst)); } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48))); FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32))); FAIL_IF(PUSH_RLDICR(reg, 31)); FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16))); return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { sljit_ins *inst = (sljit_ins*)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff); SLJIT_CACHE_FLUSH(inst, inst + 5); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_ins *inst = (sljit_ins*)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff); SLJIT_CACHE_FLUSH(inst, inst + 5); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func) { sljit_w* ptrs; if (func_ptr) *func_ptr = (void*)context; ptrs = (sljit_w*)func; context->addr = addr ? addr : ptrs[0]; context->r2 = ptrs[1]; context->r11 = ptrs[2]; } pcre-8.31/sljit/sljitNativeX86_32.c0000644000222100022210000003450211737021074013710 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* x86 32-bit arch dependent functions. */ static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm) { sljit_ub *buf; buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_w)); FAIL_IF(!buf); INC_SIZE(1 + sizeof(sljit_w)); *buf++ = opcode; *(sljit_w*)buf = imm; return SLJIT_SUCCESS; } static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type) { if (type == SLJIT_JUMP) { *code_ptr++ = 0xe9; jump->addr++; } else if (type >= SLJIT_FAST_CALL) { *code_ptr++ = 0xe8; jump->addr++; } else { *code_ptr++ = 0x0f; *code_ptr++ = get_jump_code(type); jump->addr += 2; } if (jump->flags & JUMP_LABEL) jump->flags |= PATCH_MW; else *(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4); code_ptr += 4; return code_ptr; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int size; int locals_offset; sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; compiler->args = args; compiler->flags_saved = 0; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0); #else size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0); #endif buf = (sljit_ub*)ensure_buf(compiler, 1 + size); FAIL_IF(!buf); INC_SIZE(size); PUSH_REG(reg_map[TMP_REGISTER]); #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (args > 0) { *buf++ = 0x8b; *buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3); } #endif if (saveds > 2) PUSH_REG(reg_map[SLJIT_SAVED_REG3]); if (saveds > 1) PUSH_REG(reg_map[SLJIT_SAVED_REG2]); if (saveds > 0) PUSH_REG(reg_map[SLJIT_SAVED_REG1]); #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (args > 0) { *buf++ = 0x8b; *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3]; } if (args > 1) { *buf++ = 0x8b; *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2]; } if (args > 2) { *buf++ = 0x8b; *buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3); *buf++ = 0x24; *buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */ } #else if (args > 0) { *buf++ = 0x8b; *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER]; *buf++ = sizeof(sljit_w) * 2; } if (args > 1) { *buf++ = 0x8b; *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER]; *buf++ = sizeof(sljit_w) * 3; } if (args > 2) { *buf++ = 0x8b; *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER]; *buf++ = sizeof(sljit_w) * 4; } #endif locals_offset = 2 * sizeof(sljit_uw); compiler->temporaries_start = locals_offset; if (temporaries > 3) locals_offset += (temporaries - 3) * sizeof(sljit_uw); compiler->saveds_start = locals_offset; if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); compiler->locals_offset = locals_offset; local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); #ifdef _WIN32 if (local_size > 1024) { FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size)); FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); } #endif compiler->local_size = local_size; SLJIT_ASSERT(local_size > 0); return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int locals_offset; CHECK_ERROR_VOID(); check_sljit_set_context(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; compiler->args = args; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif locals_offset = 2 * sizeof(sljit_uw); compiler->temporaries_start = locals_offset; if (temporaries > 3) locals_offset += (temporaries - 3) * sizeof(sljit_uw); compiler->saveds_start = locals_offset; if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); compiler->locals_offset = locals_offset; compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { int size; sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); SLJIT_ASSERT(compiler->args >= 0); ADJUST_LOCAL_OFFSET(src, srcw); compiler->flags_saved = 0; FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); SLJIT_ASSERT(compiler->local_size > 0); FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3); #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (compiler->args > 2) size += 2; #else if (compiler->args > 0) size += 2; #endif buf = (sljit_ub*)ensure_buf(compiler, 1 + size); FAIL_IF(!buf); INC_SIZE(size); if (compiler->saveds > 0) POP_REG(reg_map[SLJIT_SAVED_REG1]); if (compiler->saveds > 1) POP_REG(reg_map[SLJIT_SAVED_REG2]); if (compiler->saveds > 2) POP_REG(reg_map[SLJIT_SAVED_REG3]); POP_REG(reg_map[TMP_REGISTER]); #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (compiler->args > 2) RETN(sizeof(sljit_w)); else RET(); #else if (compiler->args > 0) RETN(compiler->args * sizeof(sljit_w)); else RET(); #endif return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Operators */ /* --------------------------------------------------------------------- */ /* Size contains the flags as well. */ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size, /* The register or immediate operand. */ int a, sljit_w imma, /* The general operand (not immediate). */ int b, sljit_w immb) { sljit_ub *buf; sljit_ub *buf_ptr; int flags = size & ~0xf; int inst_size; /* Both cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); /* Size flags not allowed for typed instructions. */ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); /* Both size flags cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); #if (defined SLJIT_SSE2 && SLJIT_SSE2) /* SSE2 and immediate is not possible. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); #endif size &= 0xf; inst_size = size; #if (defined SLJIT_SSE2 && SLJIT_SSE2) if (flags & EX86_PREF_F2) inst_size++; #endif if (flags & EX86_PREF_66) inst_size++; /* Calculate size of b. */ inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if ((b & 0x0f) == SLJIT_UNUSED) inst_size += sizeof(sljit_w); else if (immb != 0 && !(b & 0xf0)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) inst_size += sizeof(sljit_b); else inst_size += sizeof(sljit_w); } if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0)) b |= SLJIT_LOCALS_REG << 4; if ((b & 0xf0) != SLJIT_UNUSED) inst_size += 1; /* SIB byte. */ } /* Calculate size of a. */ if (a & SLJIT_IMM) { if (flags & EX86_BIN_INS) { if (imma <= 127 && imma >= -128) { inst_size += 1; flags |= EX86_BYTE_ARG; } else inst_size += 4; } else if (flags & EX86_SHIFT_INS) { imma &= 0x1f; if (imma != 1) { inst_size ++; flags |= EX86_BYTE_ARG; } } else if (flags & EX86_BYTE_ARG) inst_size++; else if (flags & EX86_HALF_ARG) inst_size += sizeof(short); else inst_size += sizeof(sljit_w); } else SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!buf); /* Encoding the byte. */ INC_SIZE(inst_size); #if (defined SLJIT_SSE2 && SLJIT_SSE2) if (flags & EX86_PREF_F2) *buf++ = 0xf2; #endif if (flags & EX86_PREF_66) *buf++ = 0x66; buf_ptr = buf + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81; if ((a & SLJIT_IMM) || (a == 0)) *buf_ptr = 0; #if (defined SLJIT_SSE2 && SLJIT_SSE2) else if (!(flags & EX86_SSE2)) *buf_ptr = reg_map[a] << 3; else *buf_ptr = a << 3; #else else *buf_ptr = reg_map[a] << 3; #endif } else { if (a & SLJIT_IMM) { if (imma == 1) *buf = 0xd1; else *buf = 0xc1; } else *buf = 0xd3; *buf_ptr = 0; } if (!(b & SLJIT_MEM)) #if (defined SLJIT_SSE2 && SLJIT_SSE2) *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_map[b] : b); #else *buf_ptr++ |= 0xc0 + reg_map[b]; #endif else if ((b & 0x0f) != SLJIT_UNUSED) { if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { if (immb != 0) { if (immb <= 127 && immb >= -128) *buf_ptr |= 0x40; else *buf_ptr |= 0x80; } if ((b & 0xf0) == SLJIT_UNUSED) *buf_ptr++ |= reg_map[b & 0x0f]; else { *buf_ptr++ |= 0x04; *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3); } if (immb != 0) { if (immb <= 127 && immb >= -128) *buf_ptr++ = immb; /* 8 bit displacement. */ else { *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */ buf_ptr += sizeof(sljit_w); } } } else { *buf_ptr++ |= 0x04; *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3) | (immb << 6); } } else { *buf_ptr++ |= 0x05; *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */ buf_ptr += sizeof(sljit_w); } if (a & SLJIT_IMM) { if (flags & EX86_BYTE_ARG) *buf_ptr = imma; else if (flags & EX86_HALF_ARG) *(short*)buf_ptr = imma; else if (!(flags & EX86_SHIFT_INS)) *(sljit_w*)buf_ptr = imma; } return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1); } /* --------------------------------------------------------------------- */ /* Call / return instructions */ /* --------------------------------------------------------------------- */ static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type) { sljit_ub *buf; #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); FAIL_IF(!buf); INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); if (type >= SLJIT_CALL3) PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); *buf++ = 0x8b; *buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1]; #else buf = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1); FAIL_IF(!buf); INC_SIZE(type - SLJIT_CALL0); if (type >= SLJIT_CALL3) PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); if (type >= SLJIT_CALL2) PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]); PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]); #endif return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); CHECK_EXTRA_REGS(dst, dstw, (void)0); if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); POP_REG(reg_map[dst]); return SLJIT_SUCCESS; } else if (dst & SLJIT_MEM) { buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!buf); *buf++ = 0x8f; return SLJIT_SUCCESS; } /* For UNUSED dst. Uncommon, but possible. */ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); POP_REG(reg_map[TMP_REGISTER]); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); CHECK_EXTRA_REGS(src, srcw, (void)0); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!buf); INC_SIZE(1 + 1); PUSH_REG(reg_map[src]); } else if (src & SLJIT_MEM) { buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!buf); *buf++ = 0xff; *buf |= 6 << 3; buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); } else { /* SLJIT_IMM. */ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); FAIL_IF(!buf); INC_SIZE(5 + 1); *buf++ = 0x68; *(sljit_w*)buf = srcw; buf += sizeof(sljit_w); } RET(); return SLJIT_SUCCESS; } pcre-8.31/sljit/sljitNativeX86_64.c0000644000222100022210000005122511737021074013716 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* x86 64-bit arch dependent functions. */ static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm) { sljit_ub *buf; buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w)); FAIL_IF(!buf); INC_SIZE(2 + sizeof(sljit_w)); *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); *buf++ = 0xb8 + (reg_map[reg] & 0x7); *(sljit_w*)buf = imm; return SLJIT_SUCCESS; } static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type) { if (type < SLJIT_JUMP) { *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10; *code_ptr++ = 10 + 3; } SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first); *code_ptr++ = REX_W | REX_B; *code_ptr++ = 0xb8 + 1; jump->addr = (sljit_uw)code_ptr; if (jump->flags & JUMP_LABEL) jump->flags |= PATCH_MD; else *(sljit_w*)code_ptr = jump->u.target; code_ptr += sizeof(sljit_w); *code_ptr++ = REX_B; *code_ptr++ = 0xff; *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */; return code_ptr; } static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type) { sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw)); if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) { *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */; *(sljit_w*)code_ptr = delta; } else { SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second); *code_ptr++ = REX_W | REX_B; *code_ptr++ = 0xb8 + 1; *(sljit_w*)code_ptr = addr; code_ptr += sizeof(sljit_w); *code_ptr++ = REX_B; *code_ptr++ = 0xff; *code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */; } return code_ptr; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int size, pushed_size; sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; compiler->flags_saved = 0; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif size = saveds; /* Including the return address saved by the call instruction. */ pushed_size = (saveds + 1) * sizeof(sljit_w); #ifndef _WIN64 if (saveds >= 2) size += saveds - 1; #else if (saveds >= 4) size += saveds - 3; if (temporaries >= 5) { size += (5 - 4) * 2; pushed_size += sizeof(sljit_w); } #endif size += args * 3; if (size > 0) { buf = (sljit_ub*)ensure_buf(compiler, 1 + size); FAIL_IF(!buf); INC_SIZE(size); if (saveds >= 5) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg); *buf++ = REX_B; PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]); } if (saveds >= 4) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg); *buf++ = REX_B; PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]); } if (saveds >= 3) { #ifndef _WIN64 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg); *buf++ = REX_B; #else SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg); #endif PUSH_REG(reg_lmap[SLJIT_SAVED_REG3]); } if (saveds >= 2) { #ifndef _WIN64 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg); *buf++ = REX_B; #else SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg); #endif PUSH_REG(reg_lmap[SLJIT_SAVED_REG2]); } if (saveds >= 1) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG1] < 8, saved_reg1_is_loreg); PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]); } #ifdef _WIN64 if (temporaries >= 5) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg); *buf++ = REX_B; PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); } #endif #ifndef _WIN64 if (args > 0) { *buf++ = REX_W; *buf++ = 0x8b; *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7; } if (args > 1) { *buf++ = REX_W | REX_R; *buf++ = 0x8b; *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6; } if (args > 2) { *buf++ = REX_W | REX_R; *buf++ = 0x8b; *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2; } #else if (args > 0) { *buf++ = REX_W; *buf++ = 0x8b; *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1; } if (args > 1) { *buf++ = REX_W; *buf++ = 0x8b; *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2; } if (args > 2) { *buf++ = REX_W | REX_B; *buf++ = 0x8b; *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0; } #endif } local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size; compiler->local_size = local_size; #ifdef _WIN64 if (local_size > 1024) { /* Allocate stack for the callback, which grows the stack. */ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); FAIL_IF(!buf); INC_SIZE(4); *buf++ = REX_W; *buf++ = 0x83; *buf++ = 0xc0 | (5 << 3) | 4; /* Pushed size must be divisible by 8. */ SLJIT_ASSERT(!(pushed_size & 0x7)); if (pushed_size & 0x8) { *buf++ = 5 * sizeof(sljit_w); local_size -= 5 * sizeof(sljit_w); } else { *buf++ = 4 * sizeof(sljit_w); local_size -= 4 * sizeof(sljit_w); } FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size)); FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); } #endif SLJIT_ASSERT(local_size > 0); if (local_size <= 127) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); FAIL_IF(!buf); INC_SIZE(4); *buf++ = REX_W; *buf++ = 0x83; *buf++ = 0xc0 | (5 << 3) | 4; *buf++ = local_size; } else { buf = (sljit_ub*)ensure_buf(compiler, 1 + 7); FAIL_IF(!buf); INC_SIZE(7); *buf++ = REX_W; *buf++ = 0x81; *buf++ = 0xc0 | (5 << 3) | 4; *(sljit_hw*)buf = local_size; buf += sizeof(sljit_hw); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int pushed_size; CHECK_ERROR_VOID(); check_sljit_set_context(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif /* Including the return address saved by the call instruction. */ pushed_size = (saveds + 1) * sizeof(sljit_w); #ifdef _WIN64 if (temporaries >= 5) pushed_size += sizeof(sljit_w); #endif compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { int size; sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); compiler->flags_saved = 0; FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); SLJIT_ASSERT(compiler->local_size > 0); if (compiler->local_size <= 127) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); FAIL_IF(!buf); INC_SIZE(4); *buf++ = REX_W; *buf++ = 0x83; *buf++ = 0xc0 | (0 << 3) | 4; *buf = compiler->local_size; } else { buf = (sljit_ub*)ensure_buf(compiler, 1 + 7); FAIL_IF(!buf); INC_SIZE(7); *buf++ = REX_W; *buf++ = 0x81; *buf++ = 0xc0 | (0 << 3) | 4; *(sljit_hw*)buf = compiler->local_size; } size = 1 + compiler->saveds; #ifndef _WIN64 if (compiler->saveds >= 2) size += compiler->saveds - 1; #else if (compiler->saveds >= 4) size += compiler->saveds - 3; if (compiler->temporaries >= 5) size += (5 - 4) * 2; #endif buf = (sljit_ub*)ensure_buf(compiler, 1 + size); FAIL_IF(!buf); INC_SIZE(size); #ifdef _WIN64 if (compiler->temporaries >= 5) { *buf++ = REX_B; POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); } #endif if (compiler->saveds >= 1) POP_REG(reg_map[SLJIT_SAVED_REG1]); if (compiler->saveds >= 2) { #ifndef _WIN64 *buf++ = REX_B; #endif POP_REG(reg_lmap[SLJIT_SAVED_REG2]); } if (compiler->saveds >= 3) { #ifndef _WIN64 *buf++ = REX_B; #endif POP_REG(reg_lmap[SLJIT_SAVED_REG3]); } if (compiler->saveds >= 4) { *buf++ = REX_B; POP_REG(reg_lmap[SLJIT_SAVED_EREG1]); } if (compiler->saveds >= 5) { *buf++ = REX_B; POP_REG(reg_lmap[SLJIT_SAVED_EREG2]); } RET(); return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Operators */ /* --------------------------------------------------------------------- */ static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm) { sljit_ub *buf; if (rex != 0) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw)); FAIL_IF(!buf); INC_SIZE(2 + sizeof(sljit_hw)); *buf++ = rex; *buf++ = opcode; *(sljit_hw*)buf = imm; } else { buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw)); FAIL_IF(!buf); INC_SIZE(1 + sizeof(sljit_hw)); *buf++ = opcode; *(sljit_hw*)buf = imm; } return SLJIT_SUCCESS; } static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size, /* The register or immediate operand. */ int a, sljit_w imma, /* The general operand (not immediate). */ int b, sljit_w immb) { sljit_ub *buf; sljit_ub *buf_ptr; sljit_ub rex = 0; int flags = size & ~0xf; int inst_size; /* The immediate operand must be 32 bit. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); /* Both cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); /* Size flags not allowed for typed instructions. */ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); /* Both size flags cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); #if (defined SLJIT_SSE2 && SLJIT_SSE2) /* SSE2 and immediate is not possible. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); #endif size &= 0xf; inst_size = size; if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) { if (emit_load_imm64(compiler, TMP_REG3, immb)) return NULL; immb = 0; if (b & 0xf) b |= TMP_REG3 << 4; else b |= TMP_REG3; } if (!compiler->mode32 && !(flags & EX86_NO_REXW)) rex |= REX_W; else if (flags & EX86_REX) rex |= REX; #if (defined SLJIT_SSE2 && SLJIT_SSE2) if (flags & EX86_PREF_F2) inst_size++; #endif if (flags & EX86_PREF_66) inst_size++; /* Calculate size of b. */ inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if ((b & 0x0f) == SLJIT_UNUSED) inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */ else { if (reg_map[b & 0x0f] >= 8) rex |= REX_B; if (immb != 0 && !(b & 0xf0)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) inst_size += sizeof(sljit_b); else inst_size += sizeof(sljit_hw); } } if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0)) b |= SLJIT_LOCALS_REG << 4; if ((b & 0xf0) != SLJIT_UNUSED) { inst_size += 1; /* SIB byte. */ if (reg_map[(b >> 4) & 0x0f] >= 8) rex |= REX_X; } } #if (defined SLJIT_SSE2 && SLJIT_SSE2) else if (!(flags & EX86_SSE2) && reg_map[b] >= 8) rex |= REX_B; #else else if (reg_map[b] >= 8) rex |= REX_B; #endif if (a & SLJIT_IMM) { if (flags & EX86_BIN_INS) { if (imma <= 127 && imma >= -128) { inst_size += 1; flags |= EX86_BYTE_ARG; } else inst_size += 4; } else if (flags & EX86_SHIFT_INS) { imma &= compiler->mode32 ? 0x1f : 0x3f; if (imma != 1) { inst_size ++; flags |= EX86_BYTE_ARG; } } else if (flags & EX86_BYTE_ARG) inst_size++; else if (flags & EX86_HALF_ARG) inst_size += sizeof(short); else inst_size += sizeof(sljit_hw); } else { SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */ #if (defined SLJIT_SSE2 && SLJIT_SSE2) if (!(flags & EX86_SSE2) && reg_map[a] >= 8) rex |= REX_R; #else if (reg_map[a] >= 8) rex |= REX_R; #endif } if (rex) inst_size++; buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!buf); /* Encoding the byte. */ INC_SIZE(inst_size); #if (defined SLJIT_SSE2 && SLJIT_SSE2) if (flags & EX86_PREF_F2) *buf++ = 0xf2; #endif if (flags & EX86_PREF_66) *buf++ = 0x66; if (rex) *buf++ = rex; buf_ptr = buf + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81; if ((a & SLJIT_IMM) || (a == 0)) *buf_ptr = 0; #if (defined SLJIT_SSE2 && SLJIT_SSE2) else if (!(flags & EX86_SSE2)) *buf_ptr = reg_lmap[a] << 3; else *buf_ptr = a << 3; #else else *buf_ptr = reg_lmap[a] << 3; #endif } else { if (a & SLJIT_IMM) { if (imma == 1) *buf = 0xd1; else *buf = 0xc1; } else *buf = 0xd3; *buf_ptr = 0; } if (!(b & SLJIT_MEM)) #if (defined SLJIT_SSE2 && SLJIT_SSE2) *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b); #else *buf_ptr++ |= 0xc0 + reg_lmap[b]; #endif else if ((b & 0x0f) != SLJIT_UNUSED) { if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { if (immb != 0) { if (immb <= 127 && immb >= -128) *buf_ptr |= 0x40; else *buf_ptr |= 0x80; } if ((b & 0xf0) == SLJIT_UNUSED) *buf_ptr++ |= reg_lmap[b & 0x0f]; else { *buf_ptr++ |= 0x04; *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3); } if (immb != 0) { if (immb <= 127 && immb >= -128) *buf_ptr++ = immb; /* 8 bit displacement. */ else { *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */ buf_ptr += sizeof(sljit_hw); } } } else { *buf_ptr++ |= 0x04; *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6); } } else { *buf_ptr++ |= 0x04; *buf_ptr++ = 0x25; *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */ buf_ptr += sizeof(sljit_hw); } if (a & SLJIT_IMM) { if (flags & EX86_BYTE_ARG) *buf_ptr = imma; else if (flags & EX86_HALF_ARG) *(short*)buf_ptr = imma; else if (!(flags & EX86_SHIFT_INS)) *(sljit_hw*)buf_ptr = imma; } return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1); } /* --------------------------------------------------------------------- */ /* Call / return instructions */ /* --------------------------------------------------------------------- */ static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type) { sljit_ub *buf; #ifndef _WIN64 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!buf); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { *buf++ = REX_W; *buf++ = 0x8b; *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; } *buf++ = REX_W; *buf++ = 0x8b; *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; #else SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!buf); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { *buf++ = REX_W | REX_R; *buf++ = 0x8b; *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; } *buf++ = REX_W; *buf++ = 0x8b; *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; #endif return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); /* For UNUSED dst. Uncommon, but possible. */ if (dst == SLJIT_UNUSED) dst = TMP_REGISTER; if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { if (reg_map[dst] < 8) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); POP_REG(reg_lmap[dst]); } else { buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); FAIL_IF(!buf); INC_SIZE(2); *buf++ = REX_B; POP_REG(reg_lmap[dst]); } } else if (dst & SLJIT_MEM) { /* REX_W is not necessary (src is not immediate). */ compiler->mode32 = 1; buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!buf); *buf++ = 0x8f; } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) { FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw)); src = TMP_REGISTER; } if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { if (reg_map[src] < 8) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!buf); INC_SIZE(1 + 1); PUSH_REG(reg_lmap[src]); } else { buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); FAIL_IF(!buf); INC_SIZE(2 + 1); *buf++ = REX_B; PUSH_REG(reg_lmap[src]); } } else if (src & SLJIT_MEM) { /* REX_W is not necessary (src is not immediate). */ compiler->mode32 = 1; buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!buf); *buf++ = 0xff; *buf |= 6 << 3; buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); } else { SLJIT_ASSERT(IS_HALFWORD(srcw)); /* SLJIT_IMM. */ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); FAIL_IF(!buf); INC_SIZE(5 + 1); *buf++ = 0x68; *(sljit_hw*)buf = srcw; buf += sizeof(sljit_hw); } RET(); return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Extend input */ /* --------------------------------------------------------------------- */ static int emit_mov_int(struct sljit_compiler *compiler, int sign, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; int dst_r; compiler->mode32 = 0; if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw); FAIL_IF(!code); *code = 0xc7; return SLJIT_SUCCESS; } return emit_load_imm64(compiler, dst, srcw); } compiler->mode32 = 1; code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw); FAIL_IF(!code); *code = 0xc7; compiler->mode32 = 0; return SLJIT_SUCCESS; } dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER; if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3)) dst_r = src; else { if (sign) { code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); FAIL_IF(!code); *code++ = 0x63; } else { compiler->mode32 = 1; FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); compiler->mode32 = 0; } } if (dst & SLJIT_MEM) { compiler->mode32 = 1; code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); FAIL_IF(!code); *code = 0x89; compiler->mode32 = 0; } return SLJIT_SUCCESS; } pcre-8.31/sljit/sljitConfig.h0000644000222100022210000001017311731100452013050 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _SLJIT_CONFIG_H_ #define _SLJIT_CONFIG_H_ /* --------------------------------------------------------------------- */ /* Custom defines */ /* --------------------------------------------------------------------- */ /* Put your custom defines here. This empty section will never change which helps maintaining patches (with diff / patch utilities). */ /* --------------------------------------------------------------------- */ /* Architecture */ /* --------------------------------------------------------------------- */ /* Architecture selection. */ /* #define SLJIT_CONFIG_X86_32 1 */ /* #define SLJIT_CONFIG_X86_64 1 */ /* #define SLJIT_CONFIG_ARM_V5 1 */ /* #define SLJIT_CONFIG_ARM_V7 1 */ /* #define SLJIT_CONFIG_ARM_THUMB2 1 */ /* #define SLJIT_CONFIG_PPC_32 1 */ /* #define SLJIT_CONFIG_PPC_64 1 */ /* #define SLJIT_CONFIG_MIPS_32 1 */ /* #define SLJIT_CONFIG_AUTO 1 */ /* #define SLJIT_CONFIG_UNSUPPORTED 1 */ /* --------------------------------------------------------------------- */ /* Utilities */ /* --------------------------------------------------------------------- */ /* Useful for thread-safe compiling of global functions. */ #ifndef SLJIT_UTIL_GLOBAL_LOCK /* Enabled by default */ #define SLJIT_UTIL_GLOBAL_LOCK 1 #endif /* Implements a stack like data structure (by using mmap / VirtualAlloc). */ #ifndef SLJIT_UTIL_STACK /* Enabled by default */ #define SLJIT_UTIL_STACK 1 #endif /* Single threaded application. Does not require any locks. */ #ifndef SLJIT_SINGLE_THREADED /* Disabled by default. */ #define SLJIT_SINGLE_THREADED 0 #endif /* --------------------------------------------------------------------- */ /* Configuration */ /* --------------------------------------------------------------------- */ /* If SLJIT_STD_MACROS_DEFINED is not defined, the application should define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */ #ifndef SLJIT_STD_MACROS_DEFINED /* Disabled by default. */ #define SLJIT_STD_MACROS_DEFINED 0 #endif /* Executable code allocation: If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */ #ifndef SLJIT_EXECUTABLE_ALLOCATOR /* Enabled by default. */ #define SLJIT_EXECUTABLE_ALLOCATOR 1 #endif /* Debug checks (assertions, etc.). */ #ifndef SLJIT_DEBUG /* Enabled by default */ #define SLJIT_DEBUG 1 #endif /* Verbose operations */ #ifndef SLJIT_VERBOSE /* Enabled by default */ #define SLJIT_VERBOSE 1 #endif /* See the beginning of sljitConfigInternal.h */ #endif pcre-8.31/sljit/sljitNativeARM_Thumb2.c0000644000222100022210000016441411736614113014666 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "ARM-Thumb2" SLJIT_CPUINFO; } /* Last register + 1. */ #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) #define TMP_PC (SLJIT_NO_REGISTERS + 4) #define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) #define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { 0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15 }; #define COPY_BITS(src, from, to, bits) \ ((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to)) /* Thumb16 encodings. */ #define RD3(rd) (reg_map[rd]) #define RN3(rn) (reg_map[rn] << 3) #define RM3(rm) (reg_map[rm] << 6) #define RDN3(rdn) (reg_map[rdn] << 8) #define IMM3(imm) (imm << 6) #define IMM8(imm) (imm) /* Thumb16 helpers. */ #define SET_REGS44(rd, rn) \ ((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4)) #define IS_2_LO_REGS(reg1, reg2) \ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7) #define IS_3_LO_REGS(reg1, reg2, reg3) \ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7) /* Thumb32 encodings. */ #define RD4(rd) (reg_map[rd] << 8) #define RN4(rn) (reg_map[rn] << 16) #define RM4(rm) (reg_map[rm]) #define RT4(rt) (reg_map[rt] << 12) #define DD4(dd) ((dd) << 12) #define DN4(dn) ((dn) << 16) #define DM4(dm) (dm) #define IMM5(imm) \ (COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6)) #define IMM12(imm) \ (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)) typedef sljit_ui sljit_ins; /* --------------------------------------------------------------------- */ /* Instrucion forms */ /* --------------------------------------------------------------------- */ /* dot '.' changed to _ I immediate form (possibly followed by number of immediate bits). */ #define ADCI 0xf1400000 #define ADCS 0x4140 #define ADC_W 0xeb400000 #define ADD 0x4400 #define ADDS 0x1800 #define ADDSI3 0x1c00 #define ADDSI8 0x3000 #define ADD_W 0xeb000000 #define ADDWI 0xf2000000 #define ADD_SP 0xb000 #define ADD_W 0xeb000000 #define ADD_WI 0xf1000000 #define ANDI 0xf0000000 #define ANDS 0x4000 #define AND_W 0xea000000 #define ASRS 0x4100 #define ASRSI 0x1000 #define ASR_W 0xfa40f000 #define ASR_WI 0xea4f0020 #define BICI 0xf0200000 #define BKPT 0xbe00 #define BLX 0x4780 #define BX 0x4700 #define CLZ 0xfab0f080 #define CMPI 0x2800 #define CMP_W 0xebb00f00 #define EORI 0xf0800000 #define EORS 0x4040 #define EOR_W 0xea800000 #define IT 0xbf00 #define LSLS 0x4080 #define LSLSI 0x0000 #define LSL_W 0xfa00f000 #define LSL_WI 0xea4f0000 #define LSRS 0x40c0 #define LSRSI 0x0800 #define LSR_W 0xfa20f000 #define LSR_WI 0xea4f0010 #define MOV 0x4600 #define MOVS 0x0000 #define MOVSI 0x2000 #define MOVT 0xf2c00000 #define MOVW 0xf2400000 #define MOV_W 0xea4f0000 #define MOV_WI 0xf04f0000 #define MUL 0xfb00f000 #define MVNS 0x43c0 #define MVN_W 0xea6f0000 #define MVN_WI 0xf06f0000 #define NOP 0xbf00 #define ORNI 0xf0600000 #define ORRI 0xf0400000 #define ORRS 0x4300 #define ORR_W 0xea400000 #define POP 0xbd00 #define POP_W 0xe8bd0000 #define PUSH 0xb500 #define PUSH_W 0xe92d0000 #define RSB_WI 0xf1c00000 #define RSBSI 0x4240 #define SBCI 0xf1600000 #define SBCS 0x4180 #define SBC_W 0xeb600000 #define SMULL 0xfb800000 #define STR_SP 0x9000 #define SUBS 0x1a00 #define SUBSI3 0x1e00 #define SUBSI8 0x3800 #define SUB_W 0xeba00000 #define SUBWI 0xf2a00000 #define SUB_SP 0xb080 #define SUB_WI 0xf1a00000 #define SXTB 0xb240 #define SXTB_W 0xfa4ff080 #define SXTH 0xb200 #define SXTH_W 0xfa0ff080 #define TST 0x4200 #define UMULL 0xfba00000 #define UXTB 0xb2c0 #define UXTB_W 0xfa5ff080 #define UXTH 0xb280 #define UXTH_W 0xfa1ff080 #define VABS_F64 0xeeb00bc0 #define VADD_F64 0xee300b00 #define VCMP_F64 0xeeb40b40 #define VDIV_F64 0xee800b00 #define VMOV_F64 0xeeb00b40 #define VMRS 0xeef1fa10 #define VMUL_F64 0xee200b00 #define VNEG_F64 0xeeb10b40 #define VSTR 0xed000b00 #define VSUB_F64 0xee300b40 static int push_inst16(struct sljit_compiler *compiler, sljit_ins inst) { sljit_uh *ptr; SLJIT_ASSERT(!(inst & 0xffff0000)); ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh)); FAIL_IF(!ptr); *ptr = inst; compiler->size++; return SLJIT_SUCCESS; } static int push_inst32(struct sljit_compiler *compiler, sljit_ins inst) { sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); *ptr++ = inst >> 16; *ptr = inst; compiler->size += 2; return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_imm32_const(struct sljit_compiler *compiler, int dst, sljit_uw imm) { FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); return push_inst32(compiler, MOVT | RD4(dst) | COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); } static SLJIT_INLINE void modify_imm32_const(sljit_uh* inst, sljit_uw new_imm) { int dst = inst[1] & 0x0f00; SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00)); inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1); inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff); inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1); inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); } static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) { sljit_w diff; if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; if (jump->flags & JUMP_ADDR) { /* Branch to ARM code is not optimized yet. */ if (!(jump->u.target & 0x1)) return 0; diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)) >> 1; } else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)) >> 1; } if (jump->flags & IS_CONDITIONAL) { SLJIT_ASSERT(!(jump->flags & IS_BL)); if (diff <= 127 && diff >= -128) { jump->flags |= B_TYPE1; return 5; } if (diff <= 524287 && diff >= -524288) { jump->flags |= B_TYPE2; return 4; } /* +1 comes from the prefix IT instruction. */ diff--; if (diff <= 8388607 && diff >= -8388608) { jump->flags |= B_TYPE3; return 3; } } else if (jump->flags & IS_BL) { if (diff <= 8388607 && diff >= -8388608) { jump->flags |= BL_TYPE6; return 3; } } else { if (diff <= 1023 && diff >= -1024) { jump->flags |= B_TYPE4; return 4; } if (diff <= 8388607 && diff >= -8388608) { jump->flags |= B_TYPE5; return 3; } } return 0; } static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush) { sljit_uh* inst = (sljit_uh*)addr; modify_imm32_const(inst, new_addr); if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 3); } } static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) { int type = (jump->flags >> 4) & 0xf; sljit_w diff; sljit_uh *jump_inst; int s, j1, j2; if (SLJIT_UNLIKELY(type == 0)) { inline_set_jump_addr(jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); return; } if (jump->flags & JUMP_ADDR) { SLJIT_ASSERT(jump->u.target & 0x1); diff = ((sljit_w)jump->u.target - (sljit_w)(jump->addr + 4)) >> 1; } else diff = ((sljit_w)(jump->u.label->addr) - (sljit_w)(jump->addr + 4)) >> 1; jump_inst = (sljit_uh*)jump->addr; switch (type) { case 1: /* Encoding T1 of 'B' instruction */ SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_CONDITIONAL)); jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff); return; case 2: /* Encoding T3 of 'B' instruction */ SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_CONDITIONAL)); jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1); jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff); return; case 3: SLJIT_ASSERT(jump->flags & IS_CONDITIONAL); *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8; diff--; type = 5; break; case 4: /* Encoding T2 of 'B' instruction */ SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_CONDITIONAL)); jump_inst[0] = 0xe000 | (diff & 0x7ff); return; } SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608); /* Really complex instruction form for branches. */ s = (diff >> 23) & 0x1; j1 = (~(diff >> 21) ^ s) & 0x1; j2 = (~(diff >> 22) ^ s) & 0x1; jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10); jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff); /* The others have a common form. */ if (type == 5) /* Encoding T4 of 'B' instruction */ jump_inst[1] |= 0x9000; else if (type == 6) /* Encoding T1 of 'BL' instruction */ jump_inst[1] |= 0xd000; else SLJIT_ASSERT_STOP(); } SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; sljit_uh *code; sljit_uh *code_ptr; sljit_uh *buf_ptr; sljit_uh *buf_end; sljit_uw half_count; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; CHECK_ERROR_PTR(); check_sljit_generate_code(compiler); reverse_buf(compiler); code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh)); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; code_ptr = code; half_count = 0; label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; do { buf_ptr = (sljit_uh*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 1); do { *code_ptr = *buf_ptr++; /* These structures are ordered by their address. */ SLJIT_ASSERT(!label || label->size >= half_count); SLJIT_ASSERT(!jump || jump->addr >= half_count); SLJIT_ASSERT(!const_ || const_->addr >= half_count); if (label && label->size == half_count) { label->addr = ((sljit_uw)code_ptr) | 0x1; label->size = code_ptr - code; label = label->next; } if (jump && jump->addr == half_count) { jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_CONDITIONAL) ? 10 : 8); code_ptr -= detect_jump_type(jump, code_ptr, code); jump = jump->next; } if (const_ && const_->addr == half_count) { const_->addr = (sljit_uw)code_ptr; const_ = const_->next; } code_ptr ++; half_count ++; } while (buf_ptr < buf_end); buf = buf->next; } while (buf); if (label && label->size == half_count) { label->addr = ((sljit_uw)code_ptr) | 0x1; label->size = code_ptr - code; label = label->next; } SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); jump = compiler->jumps; while (jump) { set_jump_instruction(jump); jump = jump->next; } SLJIT_CACHE_FLUSH(code, code_ptr); compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = compiler->size * sizeof(sljit_uh); /* Set thumb mode flag. */ return (void*)((sljit_uw)code | 0x1); } #define INVALID_IMM 0x80000000 static sljit_uw get_imm(sljit_uw imm) { /* Thumb immediate form. */ int counter; if (imm <= 0xff) return imm; if ((imm & 0xffff) == (imm >> 16)) { /* Some special cases. */ if (!(imm & 0xff00)) return (1 << 12) | (imm & 0xff); if (!(imm & 0xff)) return (2 << 12) | ((imm >> 8) & 0xff); if ((imm & 0xff00) == ((imm & 0xff) << 8)) return (3 << 12) | (imm & 0xff); } /* Assembly optimization: count leading zeroes? */ counter = 8; if (!(imm & 0xffff0000)) { counter += 16; imm <<= 16; } if (!(imm & 0xff000000)) { counter += 8; imm <<= 8; } if (!(imm & 0xf0000000)) { counter += 4; imm <<= 4; } if (!(imm & 0xc0000000)) { counter += 2; imm <<= 2; } if (!(imm & 0x80000000)) { counter += 1; imm <<= 1; } /* Since imm >= 128, this must be true. */ SLJIT_ASSERT(counter <= 31); if (imm & 0x00ffffff) return INVALID_IMM; /* Cannot be encoded. */ return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1); } static int load_immediate(struct sljit_compiler *compiler, int dst, sljit_uw imm) { sljit_uw tmp; if (imm >= 0x10000) { tmp = get_imm(imm); if (tmp != INVALID_IMM) return push_inst32(compiler, MOV_WI | RD4(dst) | tmp); tmp = get_imm(~imm); if (tmp != INVALID_IMM) return push_inst32(compiler, MVN_WI | RD4(dst) | tmp); } /* set low 16 bits, set hi 16 bits to 0. */ FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); /* set hi 16 bit if needed. */ if (imm >= 0x10000) return push_inst32(compiler, MOVT | RD4(dst) | COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); return SLJIT_SUCCESS; } #define ARG1_IMM 0x0010000 #define ARG2_IMM 0x0020000 #define KEEP_FLAGS 0x0040000 #define SET_MULOV 0x0080000 /* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */ #define SET_FLAGS 0x0100000 #define UNUSED_RETURN 0x0200000 #define SLOW_DEST 0x0400000 #define SLOW_SRC1 0x0800000 #define SLOW_SRC2 0x1000000 static int emit_op_imm(struct sljit_compiler *compiler, int flags, int dst, sljit_uw arg1, sljit_uw arg2) { /* dst must be register, TMP_REG1 arg1 must be register, TMP_REG1, imm arg2 must be register, TMP_REG2, imm */ int reg; sljit_uw imm, negated_imm; if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { /* Both are immediates. */ flags &= ~ARG1_IMM; FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); arg1 = TMP_REG1; } if (flags & (ARG1_IMM | ARG2_IMM)) { reg = (flags & ARG2_IMM) ? arg1 : arg2; imm = (flags & ARG2_IMM) ? arg2 : arg1; switch (flags & 0xffff) { case SLJIT_MOV: SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); return load_immediate(compiler, dst, imm); case SLJIT_NOT: if (!(flags & SET_FLAGS)) return load_immediate(compiler, dst, ~imm); /* Since the flags should be set, we just fallback to the register mode. Although I could do some clever things here, "NOT IMM" does not worth the efforts. */ break; case SLJIT_CLZ: /* No form with immediate operand. */ break; case SLJIT_ADD: negated_imm = (sljit_uw)-(sljit_w)imm; if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { if (imm <= 0x7) return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); if (negated_imm <= 0x7) return push_inst16(compiler, SUBSI3 | IMM3(negated_imm) | RD3(dst) | RN3(reg)); if (reg == dst) { if (imm <= 0xff) return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst)); if (negated_imm <= 0xff) return push_inst16(compiler, SUBSI8 | IMM8(negated_imm) | RDN3(dst)); } } if (!(flags & SET_FLAGS)) { if (imm <= 0xfff) return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm)); if (negated_imm <= 0xfff) return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(negated_imm)); } imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_ADDC: imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_SUB: if (flags & ARG2_IMM) { negated_imm = (sljit_uw)-(sljit_w)imm; if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { if (imm <= 0x7) return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); if (negated_imm <= 0x7) return push_inst16(compiler, ADDSI3 | IMM3(negated_imm) | RD3(dst) | RN3(reg)); if (reg == dst) { if (imm <= 0xff) return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst)); if (negated_imm <= 0xff) return push_inst16(compiler, ADDSI8 | IMM8(negated_imm) | RDN3(dst)); } if (imm <= 0xff && (flags & UNUSED_RETURN)) return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg)); } if (!(flags & SET_FLAGS)) { if (imm <= 0xfff) return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm)); if (negated_imm <= 0xfff) return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(negated_imm)); } imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); } else { if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst)) return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg)); imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); } break; case SLJIT_SUBC: if (flags & ARG2_IMM) { imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); } break; case SLJIT_MUL: /* No form with immediate operand. */ break; case SLJIT_AND: imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1)); if (imm != INVALID_IMM) return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_OR: imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1)); if (imm != INVALID_IMM) return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_XOR: imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_SHL: if (flags & ARG2_IMM) { imm &= 0x1f; if (imm == 0) { if (!(flags & SET_FLAGS)) return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); if (IS_2_LO_REGS(dst, reg)) return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); } if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6)); return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); } break; case SLJIT_LSHR: if (flags & ARG2_IMM) { imm &= 0x1f; if (imm == 0) { if (!(flags & SET_FLAGS)) return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); if (IS_2_LO_REGS(dst, reg)) return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); } if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6)); return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); } break; case SLJIT_ASHR: if (flags & ARG2_IMM) { imm &= 0x1f; if (imm == 0) { if (!(flags & SET_FLAGS)) return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); if (IS_2_LO_REGS(dst, reg)) return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); } if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6)); return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); } break; default: SLJIT_ASSERT_STOP(); break; } if (flags & ARG2_IMM) { FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); arg2 = TMP_REG2; } else { FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); arg1 = TMP_REG1; } } /* Both arguments are registers. */ switch (flags & 0xffff) { case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: case SLJIT_MOVU: case SLJIT_MOVU_UI: case SLJIT_MOVU_SI: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst16(compiler, MOV | SET_REGS44(dst, arg2)); case SLJIT_MOV_UB: case SLJIT_MOVU_UB: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2)); return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2)); case SLJIT_MOV_SB: case SLJIT_MOVU_SB: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2)); return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2)); case SLJIT_MOV_UH: case SLJIT_MOVU_UH: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2)); return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2)); case SLJIT_MOV_SH: case SLJIT_MOVU_SH: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2)); case SLJIT_NOT: SLJIT_ASSERT(arg1 == TMP_REG1); if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2)); case SLJIT_CLZ: SLJIT_ASSERT(arg1 == TMP_REG1); FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2))); if (flags & SET_FLAGS) { if (reg_map[dst] <= 7) return push_inst16(compiler, CMPI | RDN3(dst)); return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst)); } return SLJIT_SUCCESS; case SLJIT_ADD: if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2)); if (dst == arg1 && !(flags & SET_FLAGS)) return push_inst16(compiler, ADD | SET_REGS44(dst, arg2)); return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_ADDC: if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_SUB: if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2)); return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_SUBC: if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_MUL: if (!(flags & SET_FLAGS)) return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2)); SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2); FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2))); /* cmp TMP_REG2, dst asr #31. */ return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst)); case SLJIT_AND: if (!(flags & KEEP_FLAGS)) { if (dst == arg1 && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2)); if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2)) return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2)); } return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_OR: if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_XOR: if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_SHL: if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_LSHR: if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); case SLJIT_ASHR: if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2)); return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } #define STORE 0x01 #define SIGNED 0x02 #define WORD_SIZE 0x00 #define BYTE_SIZE 0x04 #define HALF_SIZE 0x08 #define UPDATE 0x10 #define ARG_TEST 0x20 #define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE))) #define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift))) /* 1st letter: w = word b = byte h = half 2nd letter: s = signed u = unsigned 3rd letter: l = load s = store */ static SLJIT_CONST sljit_uw sljit_mem16[12] = { /* w u l */ 0x5800 /* ldr */, /* w u s */ 0x5000 /* str */, /* w s l */ 0x5800 /* ldr */, /* w s s */ 0x5000 /* str */, /* b u l */ 0x5c00 /* ldrb */, /* b u s */ 0x5400 /* strb */, /* b s l */ 0x5600 /* ldrsb */, /* b s s */ 0x5400 /* strb */, /* h u l */ 0x5a00 /* ldrh */, /* h u s */ 0x5200 /* strh */, /* h s l */ 0x5e00 /* ldrsh */, /* h s s */ 0x5200 /* strh */, }; static SLJIT_CONST sljit_uw sljit_mem16_imm5[12] = { /* w u l */ 0x6800 /* ldr imm5 */, /* w u s */ 0x6000 /* str imm5 */, /* w s l */ 0x6800 /* ldr imm5 */, /* w s s */ 0x6000 /* str imm5 */, /* b u l */ 0x7800 /* ldrb imm5 */, /* b u s */ 0x7000 /* strb imm5 */, /* b s l */ 0x0000 /* not allowed */, /* b s s */ 0x7000 /* strb imm5 */, /* h u l */ 0x8800 /* ldrh imm5 */, /* h u s */ 0x8000 /* strh imm5 */, /* h s l */ 0x0000 /* not allowed */, /* h s s */ 0x8000 /* strh imm5 */, }; #define MEM_IMM8 0xc00 #define MEM_IMM12 0x800000 static SLJIT_CONST sljit_uw sljit_mem32[12] = { /* w u l */ 0xf8500000 /* ldr.w */, /* w u s */ 0xf8400000 /* str.w */, /* w s l */ 0xf8500000 /* ldr.w */, /* w s s */ 0xf8400000 /* str.w */, /* b u l */ 0xf8100000 /* ldrb.w */, /* b u s */ 0xf8000000 /* strb.w */, /* b s l */ 0xf9100000 /* ldrsb.w */, /* b s s */ 0xf8000000 /* strb.w */, /* h u l */ 0xf8300000 /* ldrh.w */, /* h u s */ 0xf8200000 /* strsh.w */, /* h s l */ 0xf9300000 /* ldrsh.w */, /* h s s */ 0xf8200000 /* strsh.w */, }; /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ static int emit_set_delta(struct sljit_compiler *compiler, int dst, int reg, sljit_w value) { if (value >= 0) { if (value <= 0xfff) return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value)); value = get_imm(value); if (value != INVALID_IMM) return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value); } else { value = -value; if (value <= 0xfff) return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value)); value = get_imm(value); if (value != INVALID_IMM) return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value); } return SLJIT_ERR_UNSUPPORTED; } /* Can perform an operation using at most 1 instruction. */ static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) { int tmp; SLJIT_ASSERT(arg & SLJIT_MEM); if (SLJIT_UNLIKELY(flags & UPDATE)) { if ((arg & 0xf) && !(arg & 0xf0) && argw <= 0xff && argw >= -0xff) { flags &= ~UPDATE; arg &= 0xf; if (SLJIT_UNLIKELY(flags & ARG_TEST)) return 1; if (argw >= 0) argw |= 0x200; else { argw = -argw; } SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff); FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw)); return -1; } return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } if (SLJIT_UNLIKELY(arg & 0xf0)) { argw &= 0x3; tmp = (arg >> 4) & 0xf; arg &= 0xf; if (SLJIT_UNLIKELY(flags & ARG_TEST)) return 1; if (!argw && IS_3_LO_REGS(reg, arg, tmp)) FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp))); else FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4))); return -1; } if (!(arg & 0xf) || argw > 0xfff || argw < -0xff) return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0; if (SLJIT_UNLIKELY(flags & ARG_TEST)) return 1; arg &= 0xf; if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) { tmp = 3; if (IS_WORD_SIZE(flags)) { if (OFFSET_CHECK(0x1f, 2)) tmp = 2; } else if (flags & BYTE_SIZE) { if (OFFSET_CHECK(0x1f, 0)) tmp = 0; } else { SLJIT_ASSERT(flags & HALF_SIZE); if (OFFSET_CHECK(0x1f, 1)) tmp = 1; } if (tmp != 3) { FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - tmp)))); return -1; } } /* SP based immediate. */ if (SLJIT_UNLIKELY(arg == SLJIT_LOCALS_REG) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) { FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2))); return -1; } if (argw >= 0) FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); else FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw)); return -1; } /* see getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { /* Simple operation except for updates. */ if ((arg & 0xf0) || !(next_arg & SLJIT_MEM)) return 0; if (!(arg & 0xf)) { if ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff) return 1; return 0; } if (argw == next_argw) return 1; if (arg == next_arg && ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff)) return 1; return 0; } /* Emit the necessary instructions. See can_cache above. */ static int getput_arg(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { int tmp_r; sljit_w tmp; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { next_arg = 0; next_argw = 0; } tmp_r = (flags & STORE) ? TMP_REG3 : reg; if (SLJIT_UNLIKELY(flags & UPDATE)) { flags &= ~UPDATE; /* Update only applies if a base register exists. */ if (arg & 0xf) { /* There is no caching here. */ tmp = (arg & 0xf0) >> 4; arg &= 0xf; if (!tmp) { if (!(argw & ~0xfff)) { FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw)); } if (compiler->cache_arg == SLJIT_MEM) { if (argw == compiler->cache_argw) { tmp = TMP_REG3; argw = 0; } else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { FAIL_IF(compiler->error); compiler->cache_argw = argw; tmp = TMP_REG3; argw = 0; } } if (argw) { FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); compiler->cache_arg = SLJIT_MEM; compiler->cache_argw = argw; tmp = TMP_REG3; argw = 0; } } argw &= 0x3; if (!argw && IS_3_LO_REGS(reg, arg, tmp)) { FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp))); return push_inst16(compiler, ADD | SET_REGS44(arg, tmp)); } FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4))); return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(tmp) | (argw << 6)); } } SLJIT_ASSERT(!(arg & 0xf0)); if (compiler->cache_arg == arg) { if (!((argw - compiler->cache_argw) & ~0xfff)) return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | (argw - compiler->cache_argw)); if (!((compiler->cache_argw - argw) & ~0xff)) return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw)); if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { FAIL_IF(compiler->error); return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); } } next_arg = (arg & 0xf) && (arg == next_arg); arg &= 0xf; if (arg && compiler->cache_arg == SLJIT_MEM && compiler->cache_argw == argw) return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); compiler->cache_argw = argw; if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) { FAIL_IF(compiler->error); compiler->cache_arg = SLJIT_MEM | arg; arg = 0; } else { FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); compiler->cache_arg = SLJIT_MEM; if (next_arg) { FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg))); compiler->cache_arg = SLJIT_MEM | arg; arg = 0; } } if (arg) return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); } static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; compiler->cache_arg = 0; compiler->cache_argw = 0; return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int size; sljit_ins push; CHECK_ERROR(); check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif push = (1 << 4); if (saveds >= 5) push |= 1 << 11; if (saveds >= 4) push |= 1 << 10; if (saveds >= 3) push |= 1 << 8; if (saveds >= 2) push |= 1 << 7; if (saveds >= 1) push |= 1 << 6; if (temporaries >= 5) push |= 1 << 5; FAIL_IF(saveds >= 3 ? push_inst32(compiler, PUSH_W | (1 << 14) | push) : push_inst16(compiler, PUSH | push)); /* Stack must be aligned to 8 bytes: */ size = (3 + saveds) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; compiler->local_size = local_size; if (local_size > 0) { if (local_size <= (127 << 2)) FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2))); else FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, local_size)); } if (args >= 1) FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_TEMPORARY_REG1))); if (args >= 2) FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_TEMPORARY_REG2))); if (args >= 3) FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_TEMPORARY_REG3))); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int size; CHECK_ERROR_VOID(); check_sljit_set_context(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif size = (3 + saveds) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; compiler->local_size = local_size; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { sljit_ins pop; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); if (compiler->local_size > 0) { if (compiler->local_size <= (127 << 2)) FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2))); else FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, compiler->local_size)); } pop = (1 << 4); if (compiler->saveds >= 5) pop |= 1 << 11; if (compiler->saveds >= 4) pop |= 1 << 10; if (compiler->saveds >= 3) pop |= 1 << 8; if (compiler->saveds >= 2) pop |= 1 << 7; if (compiler->saveds >= 1) pop |= 1 << 6; if (compiler->temporaries >= 5) pop |= 1 << 5; return compiler->saveds >= 3 ? push_inst32(compiler, POP_W | (1 << 15) | pop) : push_inst16(compiler, POP | pop); } /* --------------------------------------------------------------------- */ /* Operators */ /* --------------------------------------------------------------------- */ #ifdef __cplusplus extern "C" { #endif #if defined(__GNUC__) extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator); extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator); #else #error "Software divmod functions are needed" #endif #ifdef __cplusplus } #endif SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); op = GET_OPCODE(op); switch (op) { case SLJIT_BREAKPOINT: push_inst16(compiler, BKPT); break; case SLJIT_NOP: push_inst16(compiler, NOP); break; case SLJIT_UMUL: case SLJIT_SMUL: return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) | (reg_map[SLJIT_TEMPORARY_REG2] << 8) | (reg_map[SLJIT_TEMPORARY_REG1] << 12) | (reg_map[SLJIT_TEMPORARY_REG1] << 16) | reg_map[SLJIT_TEMPORARY_REG2]); case SLJIT_UDIV: case SLJIT_SDIV: if (compiler->temporaries >= 4) { FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */)); FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */)); } else if (compiler->temporaries >= 3) FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */)); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); #else #error "Software divmod functions are needed" #endif if (compiler->temporaries >= 4) { FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */)); return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */); } else if (compiler->temporaries >= 3) return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */); return SLJIT_SUCCESS; } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { int op_type, dst_r, flags; CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); compiler->cache_arg = 0; compiler->cache_argw = 0; op_type = GET_OPCODE(op); dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; if (op_type >= SLJIT_MOV && op_type <= SLJIT_MOVU_SI) { switch (op_type) { case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: flags = WORD_SIZE; break; case SLJIT_MOV_UB: flags = BYTE_SIZE; if (src & SLJIT_IMM) srcw = (unsigned char)srcw; break; case SLJIT_MOV_SB: flags = BYTE_SIZE | SIGNED; if (src & SLJIT_IMM) srcw = (signed char)srcw; break; case SLJIT_MOV_UH: flags = HALF_SIZE; if (src & SLJIT_IMM) srcw = (unsigned short)srcw; break; case SLJIT_MOV_SH: flags = HALF_SIZE | SIGNED; if (src & SLJIT_IMM) srcw = (signed short)srcw; break; case SLJIT_MOVU: case SLJIT_MOVU_UI: case SLJIT_MOVU_SI: flags = WORD_SIZE | UPDATE; break; case SLJIT_MOVU_UB: flags = BYTE_SIZE | UPDATE; if (src & SLJIT_IMM) srcw = (unsigned char)srcw; break; case SLJIT_MOVU_SB: flags = BYTE_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) srcw = (signed char)srcw; break; case SLJIT_MOVU_UH: flags = HALF_SIZE | UPDATE; if (src & SLJIT_IMM) srcw = (unsigned short)srcw; break; case SLJIT_MOVU_SH: flags = HALF_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) srcw = (signed short)srcw; break; default: SLJIT_ASSERT_STOP(); flags = 0; break; } if (src & SLJIT_IMM) FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); else if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, flags, dst_r, src, srcw)) FAIL_IF(compiler->error); else FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); } else { if (dst_r != TMP_REG1) return emit_op_imm(compiler, op_type, dst_r, TMP_REG1, src); dst_r = src; } if (dst & SLJIT_MEM) { if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) return compiler->error; else return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); } return SLJIT_SUCCESS; } if (op_type == SLJIT_NEG) { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_op2(compiler, GET_FLAGS(op) | SLJIT_SUB, dst, dstw, SLJIT_IMM, 0, src, srcw); } flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw)) FAIL_IF(compiler->error); else FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw)); src = TMP_REG2; } if (src & SLJIT_IMM) flags |= ARG2_IMM; else srcw = src; emit_op_imm(compiler, flags | op_type, dst_r, TMP_REG1, srcw); if (dst & SLJIT_MEM) { if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) return compiler->error; else return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { int dst_r, flags; CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw)) flags |= SLOW_DEST; if (src1 & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w)) FAIL_IF(compiler->error); else flags |= SLOW_SRC1; } if (src2 & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w)) FAIL_IF(compiler->error); else flags |= SLOW_SRC2; } if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w)); FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); } else { FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w)); FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); } } else if (flags & SLOW_SRC1) FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); else if (flags & SLOW_SRC2) FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); if (src1 & SLJIT_MEM) src1 = TMP_REG1; if (src2 & SLJIT_MEM) src2 = TMP_REG2; if (src1 & SLJIT_IMM) flags |= ARG1_IMM; else src1w = src1; if (src2 & SLJIT_IMM) flags |= ARG2_IMM; else src2w = src2; if (dst == SLJIT_UNUSED) flags |= UNUSED_RETURN; if (GET_OPCODE(op) == SLJIT_MUL && (op & SLJIT_SET_O)) flags |= SET_MULOV; emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); if (dst & SLJIT_MEM) { if (!(flags & SLOW_DEST)) { getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw); return compiler->error; } return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); SLJIT_ASSERT(size == 2 || size == 4); if (size == 2) return push_inst16(compiler, *(sljit_uh*)instruction); return push_inst32(compiler, *(sljit_ins*)instruction); } /* --------------------------------------------------------------------- */ /* Floating point operators */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { return 1; } static int emit_fop_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) { sljit_w tmp; sljit_w inst = VSTR | ((flags & STORE) ? 0 : 0x00100000); SLJIT_ASSERT(arg & SLJIT_MEM); /* Fast loads and stores. */ if (SLJIT_UNLIKELY(arg & 0xf0)) { FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & 0xf) | RM4((arg & 0xf0) >> 4) | ((argw & 0x3) << 6))); arg = SLJIT_MEM | TMP_REG2; argw = 0; } if (arg & 0xf) { if (!(argw & ~0x3fc)) return push_inst32(compiler, inst | 0x800000 | RN4(arg & 0xf) | DD4(reg) | (argw >> 2)); if (!(-argw & ~0x3fc)) return push_inst32(compiler, inst | RN4(arg & 0xf) | DD4(reg) | (-argw >> 2)); } SLJIT_ASSERT(!(arg & 0xf0)); if (compiler->cache_arg == arg) { tmp = argw - compiler->cache_argw; if (!(tmp & ~0x3fc)) return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2)); if (!(-tmp & ~0x3fc)) return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2)); if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) { FAIL_IF(compiler->error); compiler->cache_argw = argw; return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); } } compiler->cache_arg = arg; compiler->cache_argw = argw; if (SLJIT_UNLIKELY(!(arg & 0xf))) FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); else if (emit_set_delta(compiler, TMP_REG3, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) FAIL_IF(compiler->error); else { FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); if (arg & 0xf) FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & 0xf)))); } return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { int dst_r; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); compiler->cache_arg = 0; compiler->cache_argw = 0; if (GET_OPCODE(op) == SLJIT_FCMP) { if (dst & SLJIT_MEM) { emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); dst = TMP_FREG1; } if (src & SLJIT_MEM) { emit_fop_mem(compiler, 0, TMP_FREG2, src, srcw); src = TMP_FREG2; } FAIL_IF(push_inst32(compiler, VCMP_F64 | DD4(dst) | DM4(src))); return push_inst32(compiler, VMRS); } dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { emit_fop_mem(compiler, 0, dst_r, src, srcw); src = dst_r; } switch (GET_OPCODE(op)) { case SLJIT_FMOV: if (src != dst_r) FAIL_IF(push_inst32(compiler, VMOV_F64 | DD4(dst_r) | DM4(src))); break; case SLJIT_FNEG: FAIL_IF(push_inst32(compiler, VNEG_F64 | DD4(dst_r) | DM4(src))); break; case SLJIT_FABS: FAIL_IF(push_inst32(compiler, VABS_F64 | DD4(dst_r) | DM4(src))); break; } if (dst & SLJIT_MEM) return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { int dst_r; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { emit_fop_mem(compiler, 0, TMP_FREG1, src1, src1w); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { emit_fop_mem(compiler, 0, TMP_FREG2, src2, src2w); src2 = TMP_FREG2; } switch (GET_OPCODE(op)) { case SLJIT_FADD: FAIL_IF(push_inst32(compiler, VADD_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; case SLJIT_FSUB: FAIL_IF(push_inst32(compiler, VSUB_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; case SLJIT_FMUL: FAIL_IF(push_inst32(compiler, VMUL_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; case SLJIT_FDIV: FAIL_IF(push_inst32(compiler, VDIV_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; } if (dst & SLJIT_MEM) return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); else if (dst & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) return compiler->error; FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); compiler->cache_arg = 0; compiler->cache_argw = 0; return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src))); else if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw)) FAIL_IF(compiler->error); else { compiler->cache_arg = 0; compiler->cache_argw = 0; FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0)); FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2))); } } else if (src & SLJIT_IMM) FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); return push_inst16(compiler, BLX | RN3(TMP_REG3)); } /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ static sljit_uw get_cc(int type) { switch (type) { case SLJIT_C_EQUAL: case SLJIT_C_MUL_NOT_OVERFLOW: case SLJIT_C_FLOAT_EQUAL: return 0x0; case SLJIT_C_NOT_EQUAL: case SLJIT_C_MUL_OVERFLOW: case SLJIT_C_FLOAT_NOT_EQUAL: return 0x1; case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: return 0x3; case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: return 0x2; case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: return 0x8; case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: return 0x9; case SLJIT_C_SIG_LESS: return 0xb; case SLJIT_C_SIG_GREATER_EQUAL: return 0xa; case SLJIT_C_SIG_GREATER: return 0xc; case SLJIT_C_SIG_LESS_EQUAL: return 0xd; case SLJIT_C_OVERFLOW: case SLJIT_C_FLOAT_NAN: return 0x6; case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_FLOAT_NOT_NAN: return 0x7; default: /* SLJIT_JUMP */ return 0xe; } } SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { struct sljit_label *label; CHECK_ERROR_PTR(); check_sljit_emit_label(compiler); if (compiler->last_label && compiler->last_label->size == compiler->size) return compiler->last_label; label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); PTR_FAIL_IF(!label); set_label(label, compiler); return label; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; int cc; CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; /* In ARM, we don't need to touch the arguments. */ PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); if (type < SLJIT_JUMP) { jump->flags |= IS_CONDITIONAL; cc = get_cc(type); jump->flags |= cc << 8; PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); } jump->addr = compiler->size; if (type <= SLJIT_JUMP) PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1))); else { jump->flags |= IS_BL; PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1))); } return jump; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { struct sljit_jump *jump; CHECK_ERROR(); check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); /* In ARM, we don't need to touch the arguments. */ if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); jump->u.target = srcw; FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); jump->addr = compiler->size; FAIL_IF(push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1))); } else { if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src)); FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw)); if (type >= SLJIT_FAST_CALL) return push_inst16(compiler, BLX | RN3(TMP_REG1)); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { int dst_r; sljit_uw cc; CHECK_ERROR(); check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; cc = get_cc(type); if (GET_OPCODE(op) == SLJIT_OR && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); FAIL_IF(push_inst32(compiler, ORRI | RN4(dst) | RD4(dst) | 0x1)); if (op & SLJIT_SET_E) { if (reg_map[dst] <= 7) return push_inst16(compiler, ORRS | RD3(dst) | RN3(dst)); return push_inst32(compiler, ORR_W | SET_FLAGS | RD4(TMP_REG1) | RN4(dst) | RM4(dst)); } return SLJIT_SUCCESS; } dst_r = TMP_REG2; if (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && reg_map[dst] <= 7) dst_r = dst; FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); FAIL_IF(push_inst16(compiler, MOVSI | 0x1 | RDN3(dst_r))); FAIL_IF(push_inst16(compiler, MOVSI | 0x0 | RDN3(dst_r))); if (dst_r == TMP_REG2) { if (GET_OPCODE(op) == SLJIT_OR) { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG2, 0); } if (dst & SLJIT_MEM) return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw); else return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2)); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; int dst_r; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); ADJUST_LOCAL_OFFSET(dst, dstw); const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); set_const(const_, compiler); dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw)); return const_; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { inline_set_jump_addr(addr, new_addr, 1); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_uh* inst = (sljit_uh*)addr; modify_imm32_const(inst, new_constant); SLJIT_CACHE_FLUSH(inst, inst + 3); } pcre-8.31/sljit/sljitNativeARM_v5.c0000644000222100022210000022167311736614113014060 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return "ARMv7" SLJIT_CPUINFO; #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) return "ARMv5" SLJIT_CPUINFO; #else #error "Internal error: Unknown ARM architecture" #endif } /* Last register + 1. */ #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) #define TMP_PC (SLJIT_NO_REGISTERS + 4) #define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) #define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* In ARM instruction words. Cache lines are usually 32 byte aligned. */ #define CONST_POOL_ALIGNMENT 8 #define CONST_POOL_EMPTY 0xffffffff #define ALIGN_INSTRUCTION(ptr) \ (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) #define MAX_DIFFERENCE(max_diff) \ (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { 0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15 }; #define RM(rm) (reg_map[rm]) #define RD(rd) (reg_map[rd] << 12) #define RN(rn) (reg_map[rn] << 16) /* --------------------------------------------------------------------- */ /* Instrucion forms */ /* --------------------------------------------------------------------- */ /* The instruction includes the AL condition. INST_NAME - CONDITIONAL remove this flag. */ #define COND_MASK 0xf0000000 #define CONDITIONAL 0xe0000000 #define PUSH_POOL 0xff000000 /* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */ #define ADC_DP 0x5 #define ADD_DP 0x4 #define AND_DP 0x0 #define B 0xea000000 #define BIC_DP 0xe #define BL 0xeb000000 #define BLX 0xe12fff30 #define BX 0xe12fff10 #define CLZ 0xe16f0f10 #define CMP_DP 0xa #define BKPT 0xe1200070 #define EOR_DP 0x1 #define MOV_DP 0xd #define MUL 0xe0000090 #define MVN_DP 0xf #define NOP 0xe1a00000 #define ORR_DP 0xc #define PUSH 0xe92d0000 #define POP 0xe8bd0000 #define RSB_DP 0x3 #define RSC_DP 0x7 #define SBC_DP 0x6 #define SMULL 0xe0c00090 #define SUB_DP 0x2 #define UMULL 0xe0800090 #define VABS_F64 0xeeb00bc0 #define VADD_F64 0xee300b00 #define VCMP_F64 0xeeb40b40 #define VDIV_F64 0xee800b00 #define VMOV_F64 0xeeb00b40 #define VMRS 0xeef1fa10 #define VMUL_F64 0xee200b00 #define VNEG_F64 0xeeb10b40 #define VSTR 0xed000b00 #define VSUB_F64 0xee300b40 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Arm v7 specific instructions. */ #define MOVW 0xe3000000 #define MOVT 0xe3400000 #define SXTB 0xe6af0070 #define SXTH 0xe6bf0070 #define UXTB 0xe6ef0070 #define UXTH 0xe6ff0070 #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) static int push_cpool(struct sljit_compiler *compiler) { /* Pushing the constant pool into the instruction stream. */ sljit_uw* inst; sljit_uw* cpool_ptr; sljit_uw* cpool_end; int i; /* The label could point the address after the constant pool. */ if (compiler->last_label && compiler->last_label->size == compiler->size) compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1; SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE); inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); FAIL_IF(!inst); compiler->size++; *inst = 0xff000000 | compiler->cpool_fill; for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) { inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); FAIL_IF(!inst); compiler->size++; *inst = 0; } cpool_ptr = compiler->cpool; cpool_end = cpool_ptr + compiler->cpool_fill; while (cpool_ptr < cpool_end) { inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); FAIL_IF(!inst); compiler->size++; *inst = *cpool_ptr++; } compiler->cpool_diff = CONST_POOL_EMPTY; compiler->cpool_fill = 0; return SLJIT_SUCCESS; } static int push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) FAIL_IF(push_cpool(compiler)); ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); FAIL_IF(!ptr); compiler->size++; *ptr = inst; return SLJIT_SUCCESS; } static int push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; sljit_uw cpool_index = CPOOL_SIZE; sljit_uw* cpool_ptr; sljit_uw* cpool_end; sljit_ub* cpool_unique_ptr; if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) FAIL_IF(push_cpool(compiler)); else if (compiler->cpool_fill > 0) { cpool_ptr = compiler->cpool; cpool_end = cpool_ptr + compiler->cpool_fill; cpool_unique_ptr = compiler->cpool_unique; do { if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) { cpool_index = cpool_ptr - compiler->cpool; break; } cpool_ptr++; cpool_unique_ptr++; } while (cpool_ptr < cpool_end); } if (cpool_index == CPOOL_SIZE) { /* Must allocate a new entry in the literal pool. */ if (compiler->cpool_fill < CPOOL_SIZE) { cpool_index = compiler->cpool_fill; compiler->cpool_fill++; } else { FAIL_IF(push_cpool(compiler)); cpool_index = 0; compiler->cpool_fill = 1; } } SLJIT_ASSERT((inst & 0xfff) == 0); ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); FAIL_IF(!ptr); compiler->size++; *ptr = inst | cpool_index; compiler->cpool[cpool_index] = literal; compiler->cpool_unique[cpool_index] = 0; if (compiler->cpool_diff == CONST_POOL_EMPTY) compiler->cpool_diff = compiler->size; return SLJIT_SUCCESS; } static int push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) FAIL_IF(push_cpool(compiler)); SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0); ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); FAIL_IF(!ptr); compiler->size++; *ptr = inst | compiler->cpool_fill; compiler->cpool[compiler->cpool_fill] = literal; compiler->cpool_unique[compiler->cpool_fill] = 1; compiler->cpool_fill++; if (compiler->cpool_diff == CONST_POOL_EMPTY) compiler->cpool_diff = compiler->size; return SLJIT_SUCCESS; } static SLJIT_INLINE int prepare_blx(struct sljit_compiler *compiler) { /* Place for at least two instruction (doesn't matter whether the first has a literal). */ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088))) return push_cpool(compiler); return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_blx(struct sljit_compiler *compiler) { /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */ SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092)); return push_inst(compiler, BLX | RM(TMP_REG1)); } static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size) { sljit_uw diff; sljit_uw ind; sljit_uw counter = 0; sljit_uw* clear_const_pool = const_pool; sljit_uw* clear_const_pool_end = const_pool + cpool_size; SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT); /* Set unused flag for all literals in the constant pool. I.e.: unused literals can belong to branches, which can be encoded as B or BL. We can "compress" the constant pool by discarding these literals. */ while (clear_const_pool < clear_const_pool_end) *clear_const_pool++ = (sljit_uw)(-1); while (last_pc_patch < code_ptr) { /* Data transfer instruction with Rn == r15. */ if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) { diff = const_pool - last_pc_patch; ind = (*last_pc_patch) & 0xfff; /* Must be a load instruction with immediate offset. */ SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20))); if ((int)const_pool[ind] < 0) { const_pool[ind] = counter; ind = counter; counter++; } else ind = const_pool[ind]; SLJIT_ASSERT(diff >= 1); if (diff >= 2 || ind > 0) { diff = (diff + ind - 2) << 2; SLJIT_ASSERT(diff <= 0xfff); *last_pc_patch = (*last_pc_patch & ~0xfff) | diff; } else *last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004; } last_pc_patch++; } return counter; } /* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */ struct future_patch { struct future_patch* next; int index; int value; }; static SLJIT_INLINE int resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) { int value; struct future_patch *curr_patch, *prev_patch; /* Using the values generated by patch_pc_relative_loads. */ if (!*first_patch) value = (int)cpool_start_address[cpool_current_index]; else { curr_patch = *first_patch; prev_patch = 0; while (1) { if (!curr_patch) { value = (int)cpool_start_address[cpool_current_index]; break; } if ((sljit_uw)curr_patch->index == cpool_current_index) { value = curr_patch->value; if (prev_patch) prev_patch->next = curr_patch->next; else *first_patch = curr_patch->next; SLJIT_FREE(curr_patch); break; } prev_patch = curr_patch; curr_patch = curr_patch->next; } } if (value >= 0) { if ((sljit_uw)value > cpool_current_index) { curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch)); if (!curr_patch) { while (*first_patch) { curr_patch = *first_patch; *first_patch = (*first_patch)->next; SLJIT_FREE(curr_patch); } return SLJIT_ERR_ALLOC_FAILED; } curr_patch->next = *first_patch; curr_patch->index = value; curr_patch->value = cpool_start_address[value]; *first_patch = curr_patch; } cpool_start_address[value] = *buf_ptr; } return SLJIT_SUCCESS; } #else static int push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); FAIL_IF(!ptr); compiler->size++; *ptr = inst; return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_imm(struct sljit_compiler *compiler, int reg, sljit_w imm) { FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); } #endif static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) { sljit_w diff; if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) if (jump->flags & IS_BL) code_ptr--; if (jump->flags & JUMP_ADDR) diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)); else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)); } /* Branch to Thumb code has not been optimized yet. */ if (diff & 0x3) return 0; diff >>= 2; if (jump->flags & IS_BL) { if (diff <= 0x01ffffff && diff >= -0x02000000) { *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK); jump->flags |= PATCH_B; return 1; } } else { if (diff <= 0x01ffffff && diff >= -0x02000000) { *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); jump->flags |= PATCH_B; } } #else if (jump->flags & JUMP_ADDR) diff = ((sljit_w)jump->u.target - (sljit_w)code_ptr); else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)code_ptr); } /* Branch to Thumb code has not been optimized yet. */ if (diff & 0x3) return 0; diff >>= 2; if (diff <= 0x01ffffff && diff >= -0x02000000) { code_ptr -= 2; *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK); jump->flags |= PATCH_B; return 1; } #endif return 0; } static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; sljit_uw *inst = (sljit_uw*)ptr[0]; sljit_uw mov_pc = ptr[1]; int bl = (mov_pc & 0x0000f000) != RD(TMP_PC); sljit_w diff = (sljit_w)(((sljit_w)new_addr - (sljit_w)(inst + 2)) >> 2); if (diff <= 0x7fffff && diff >= -0x800000) { /* Turn to branch. */ if (!bl) { inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff); inst[1] = NOP; if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 2); } } } else { /* Get the position of the constant. */ if (mov_pc & (1 << 23)) ptr = inst + ((mov_pc & 0xfff) >> 2) + 2; else ptr = inst + 1; if (*inst != mov_pc) { inst[0] = mov_pc; if (!bl) { if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { inst[1] = BLX | RM(TMP_REG1); if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 2); } } } *ptr = new_addr; } #else sljit_uw *inst = (sljit_uw*)addr; SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff); inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff); if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 2); } #endif } static sljit_uw get_immediate(sljit_uw imm); static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_w new_constant, int flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; sljit_uw *inst = (sljit_uw*)ptr[0]; sljit_uw ldr_literal = ptr[1]; sljit_uw src2; src2 = get_immediate(new_constant); if (src2) { *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 1); } return; } src2 = get_immediate(~new_constant); if (src2) { *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2; if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 1); } return; } if (ldr_literal & (1 << 23)) ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2; else ptr = inst + 1; if (*inst != ldr_literal) { *inst = ldr_literal; if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 1); } } *ptr = new_constant; #else sljit_uw *inst = (sljit_uw*)addr; SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff); inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff); if (flush) { SLJIT_CACHE_FLUSH(inst, inst + 2); } #endif } SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; sljit_uw *code; sljit_uw *code_ptr; sljit_uw *buf_ptr; sljit_uw *buf_end; sljit_uw size; sljit_uw word_count; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw cpool_size; sljit_uw cpool_skip_alignment; sljit_uw cpool_current_index; sljit_uw *cpool_start_address; sljit_uw *last_pc_patch; struct future_patch *first_patch; #endif struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; CHECK_ERROR_PTR(); check_sljit_generate_code(compiler); reverse_buf(compiler); /* Second code generation pass. */ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) size = compiler->size + (compiler->patches << 1); if (compiler->cpool_fill > 0) size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1; #else size = compiler->size; #endif code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw)); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) cpool_size = 0; cpool_skip_alignment = 0; cpool_current_index = 0; cpool_start_address = NULL; first_patch = NULL; last_pc_patch = code; #endif code_ptr = code; word_count = 0; label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; if (label && label->size == 0) { label->addr = (sljit_uw)code; label->size = 0; label = label->next; } do { buf_ptr = (sljit_uw*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { word_count++; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) if (cpool_size > 0) { if (cpool_skip_alignment > 0) { buf_ptr++; cpool_skip_alignment--; } else { if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { SLJIT_FREE_EXEC(code); compiler->error = SLJIT_ERR_ALLOC_FAILED; return NULL; } buf_ptr++; if (++cpool_current_index >= cpool_size) { SLJIT_ASSERT(!first_patch); cpool_size = 0; if (label && label->size == word_count) { /* Points after the current instruction. */ label->addr = (sljit_uw)code_ptr; label->size = code_ptr - code; label = label->next; } } } } else if ((*buf_ptr & 0xff000000) != PUSH_POOL) { #endif *code_ptr = *buf_ptr++; /* These structures are ordered by their address. */ SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) if (detect_jump_type(jump, code_ptr, code)) code_ptr--; jump->addr = (sljit_uw)code_ptr; #else jump->addr = (sljit_uw)(code_ptr - 2); if (detect_jump_type(jump, code_ptr, code)) code_ptr -= 2; #endif jump = jump->next; } if (label && label->size == word_count) { /* code_ptr can be affected above. */ label->addr = (sljit_uw)(code_ptr + 1); label->size = (code_ptr + 1) - code; label = label->next; } if (const_ && const_->addr == word_count) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) const_->addr = (sljit_uw)code_ptr; #else const_->addr = (sljit_uw)(code_ptr - 1); #endif const_ = const_->next; } code_ptr++; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) } else { /* Fortunately, no need to shift. */ cpool_size = *buf_ptr++ & ~PUSH_POOL; SLJIT_ASSERT(cpool_size > 0); cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1); cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size); if (cpool_current_index > 0) { /* Unconditional branch. */ *code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); code_ptr = cpool_start_address + cpool_current_index; } cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1; cpool_current_index = 0; last_pc_patch = code_ptr; } #endif } while (buf_ptr < buf_end); buf = buf->next; } while (buf); SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) SLJIT_ASSERT(cpool_size == 0); if (compiler->cpool_fill > 0) { cpool_start_address = ALIGN_INSTRUCTION(code_ptr); cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill); if (cpool_current_index > 0) code_ptr = cpool_start_address + cpool_current_index; buf_ptr = compiler->cpool; buf_end = buf_ptr + compiler->cpool_fill; cpool_current_index = 0; while (buf_ptr < buf_end) { if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { SLJIT_FREE_EXEC(code); compiler->error = SLJIT_ERR_ALLOC_FAILED; return NULL; } buf_ptr++; cpool_current_index++; } SLJIT_ASSERT(!first_patch); } #endif jump = compiler->jumps; while (jump) { buf_ptr = (sljit_uw*)jump->addr; if (jump->flags & PATCH_B) { if (!(jump->flags & JUMP_ADDR)) { SLJIT_ASSERT(jump->flags & JUMP_LABEL); SLJIT_ASSERT(((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >= -0x02000000); *buf_ptr |= (((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff; } else { SLJIT_ASSERT(((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >= -0x02000000); *buf_ptr |= (((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff; } } else if (jump->flags & SLJIT_REWRITABLE_JUMP) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) jump->addr = (sljit_uw)code_ptr; code_ptr[0] = (sljit_uw)buf_ptr; code_ptr[1] = *buf_ptr; inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); code_ptr += 2; #else inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); #endif } else { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) if (jump->flags & IS_BL) buf_ptr--; if (*buf_ptr & (1 << 23)) buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; else buf_ptr += 1; *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; #else inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); #endif } jump = jump->next; } #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) const_ = compiler->consts; while (const_) { buf_ptr = (sljit_uw*)const_->addr; const_->addr = (sljit_uw)code_ptr; code_ptr[0] = (sljit_uw)buf_ptr; code_ptr[1] = *buf_ptr; if (*buf_ptr & (1 << 23)) buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; else buf_ptr += 1; /* Set the value again (can be a simple constant). */ inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0); code_ptr += 2; const_ = const_->next; } #endif SLJIT_ASSERT(code_ptr - code <= (int)size); SLJIT_CACHE_FLUSH(code, code_ptr); compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = size * sizeof(sljit_uw); return code; } /* emit_op inp_flags. WRITE_BACK must be the first, since it is a flag. */ #define WRITE_BACK 0x01 #define ALLOW_IMM 0x02 #define ALLOW_INV_IMM 0x04 #define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) #define ARG_TEST 0x08 /* Creates an index in data_transfer_insts array. */ #define WORD_DATA 0x00 #define BYTE_DATA 0x10 #define HALF_DATA 0x20 #define SIGNED_DATA 0x40 #define LOAD_DATA 0x80 #define EMIT_INSTRUCTION(inst) \ FAIL_IF(push_inst(compiler, (inst))) /* Condition: AL. */ #define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \ (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2)) static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w); SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int size; sljit_uw push; CHECK_ERROR(); check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif /* Push saved registers, temporary registers stmdb sp!, {..., lr} */ push = PUSH | (1 << 14); if (temporaries >= 5) push |= 1 << 11; if (temporaries >= 4) push |= 1 << 10; if (saveds >= 5) push |= 1 << 8; if (saveds >= 4) push |= 1 << 7; if (saveds >= 3) push |= 1 << 6; if (saveds >= 2) push |= 1 << 5; if (saveds >= 1) push |= 1 << 4; EMIT_INSTRUCTION(push); /* Stack must be aligned to 8 bytes: */ size = (1 + saveds) * sizeof(sljit_uw); if (temporaries >= 4) size += (temporaries - 3) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; compiler->local_size = local_size; if (local_size > 0) FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size)); if (args >= 1) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1))); if (args >= 2) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); if (args >= 3) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3))); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { int size; CHECK_ERROR_VOID(); check_sljit_set_context(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif size = (1 + saveds) * sizeof(sljit_uw); if (temporaries >= 4) size += (temporaries - 3) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; compiler->local_size = local_size; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { sljit_uw pop; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); if (compiler->local_size > 0) FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); pop = POP | (1 << 15); /* Push saved registers, temporary registers ldmia sp!, {..., pc} */ if (compiler->temporaries >= 5) pop |= 1 << 11; if (compiler->temporaries >= 4) pop |= 1 << 10; if (compiler->saveds >= 5) pop |= 1 << 8; if (compiler->saveds >= 4) pop |= 1 << 7; if (compiler->saveds >= 3) pop |= 1 << 6; if (compiler->saveds >= 2) pop |= 1 << 5; if (compiler->saveds >= 1) pop |= 1 << 4; return push_inst(compiler, pop); } /* --------------------------------------------------------------------- */ /* Operators */ /* --------------------------------------------------------------------- */ /* s/l - store/load (1 bit) u/s - signed/unsigned (1 bit) w/b/h/N - word/byte/half/NOT allowed (2 bit) It contans 16 items, but not all are different. */ static sljit_w data_transfer_insts[16] = { /* s u w */ 0xe5000000 /* str */, /* s u b */ 0xe5400000 /* strb */, /* s u h */ 0xe10000b0 /* strh */, /* s u N */ 0x00000000 /* not allowed */, /* s s w */ 0xe5000000 /* str */, /* s s b */ 0xe5400000 /* strb */, /* s s h */ 0xe10000b0 /* strh */, /* s s N */ 0x00000000 /* not allowed */, /* l u w */ 0xe5100000 /* ldr */, /* l u b */ 0xe5500000 /* ldrb */, /* l u h */ 0xe11000b0 /* ldrh */, /* l u N */ 0x00000000 /* not allowed */, /* l s w */ 0xe5100000 /* ldr */, /* l s b */ 0xe11000d0 /* ldrsb */, /* l s h */ 0xe11000f0 /* ldrsh */, /* l s N */ 0x00000000 /* not allowed */, }; #define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \ (data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2)) /* Normal ldr/str instruction. Type2: ldrsb, ldrh, ldrsh */ #define IS_TYPE1_TRANSFER(type) \ (data_transfer_insts[(type) >> 4] & 0x04000000) #define TYPE2_TRANSFER_IMM(imm) \ (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22)) /* flags: */ /* Arguments are swapped. */ #define ARGS_SWAPPED 0x01 /* Inverted immediate. */ #define INV_IMM 0x02 /* Source and destination is register. */ #define REG_DEST 0x04 #define REG_SOURCE 0x08 /* One instruction is enough. */ #define FAST_DEST 0x10 /* Multiple instructions are required. */ #define SLOW_DEST 0x20 /* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */ #define SET_FLAGS (1 << 20) /* dst: reg src1: reg src2: reg or imm (if allowed) SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */ #define SRC2_IMM (1 << 25) #define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2))) #define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2)) #define EMIT_SHIFT_INS_AND_RETURN(opcode) \ SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \ if (compiler->shift_imm != 0x20) { \ SLJIT_ASSERT(src1 == TMP_REG1); \ SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \ if (compiler->shift_imm != 0) \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \ } \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, int dst, int src1, int src2) { sljit_w mul_inst; switch (GET_OPCODE(op)) { case SLJIT_ADD: SLJIT_ASSERT(!(flags & INV_IMM)); EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP); case SLJIT_ADDC: SLJIT_ASSERT(!(flags & INV_IMM)); EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP); case SLJIT_SUB: SLJIT_ASSERT(!(flags & INV_IMM)); if (!(flags & ARGS_SWAPPED)) EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP); EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP); case SLJIT_SUBC: SLJIT_ASSERT(!(flags & INV_IMM)); if (!(flags & ARGS_SWAPPED)) EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP); EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP); case SLJIT_MUL: SLJIT_ASSERT(!(flags & INV_IMM)); SLJIT_ASSERT(!(src2 & SRC2_IMM)); if (SLJIT_UNLIKELY(op & SLJIT_SET_O)) mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12); else mul_inst = MUL | (reg_map[dst] << 16); if (dst != src2) FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2])); else if (dst != src1) FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1])); else { /* Rm and Rd must not be the same register. */ SLJIT_ASSERT(dst != TMP_REG1); FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2]))); FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1])); } if (!(op & SLJIT_SET_O)) return SLJIT_SUCCESS; /* We need to use TMP_REG3. */ compiler->cache_arg = 0; compiler->cache_argw = 0; /* cmp TMP_REG2, dst asr #31. */ return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0)); case SLJIT_AND: if (!(flags & INV_IMM)) EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP); EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP); case SLJIT_OR: SLJIT_ASSERT(!(flags & INV_IMM)); EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP); case SLJIT_XOR: SLJIT_ASSERT(!(flags & INV_IMM)); EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP); case SLJIT_SHL: EMIT_SHIFT_INS_AND_RETURN(0); case SLJIT_LSHR: EMIT_SHIFT_INS_AND_RETURN(1); case SLJIT_ASHR: EMIT_SHIFT_INS_AND_RETURN(2); case SLJIT_MOV: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if (dst != src2) { if (src2 & SRC2_IMM) { if (flags & INV_IMM) EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); } EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]); } return SLJIT_SUCCESS; case SLJIT_MOV_UB: case SLJIT_MOV_SB: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) if (op == SLJIT_MOV_UB) return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2])); return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); #else return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); #endif } else if (dst != src2) { SLJIT_ASSERT(src2 & SRC2_IMM); if (flags & INV_IMM) EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); } return SLJIT_SUCCESS; case SLJIT_MOV_UH: case SLJIT_MOV_SH: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2])); return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); #else return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); #endif } else if (dst != src2) { SLJIT_ASSERT(src2 & SRC2_IMM); if (flags & INV_IMM) EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); } return SLJIT_SUCCESS; case SLJIT_NOT: if (src2 & SRC2_IMM) { if (flags & INV_IMM) EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); } EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2)); case SLJIT_CLZ: SLJIT_ASSERT(!(flags & INV_IMM)); SLJIT_ASSERT(!(src2 & SRC2_IMM)); FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); if (flags & SET_FLAGS) EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM); return SLJIT_SUCCESS; } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } #undef EMIT_DATA_PROCESS_INS_AND_RETURN #undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN #undef EMIT_SHIFT_INS_AND_RETURN /* Tests whether the immediate can be stored in the 12 bit imm field. Returns with 0 if not possible. */ static sljit_uw get_immediate(sljit_uw imm) { int rol; if (imm <= 0xff) return SRC2_IMM | imm; if (!(imm & 0xff000000)) { imm <<= 8; rol = 8; } else { imm = (imm << 24) | (imm >> 8); rol = 0; } if (!(imm & 0xff000000)) { imm <<= 8; rol += 4; } if (!(imm & 0xf0000000)) { imm <<= 4; rol += 2; } if (!(imm & 0xc0000000)) { imm <<= 2; rol += 1; } if (!(imm & 0x00ffffff)) return SRC2_IMM | (imm >> 24) | (rol << 8); else return 0; } #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) static int generate_int(struct sljit_compiler *compiler, int reg, sljit_uw imm, int positive) { sljit_uw mask; sljit_uw imm1; sljit_uw imm2; int rol; /* Step1: Search a zero byte (8 continous zero bit). */ mask = 0xff000000; rol = 8; while(1) { if (!(imm & mask)) { /* Rol imm by rol. */ imm = (imm << rol) | (imm >> (32 - rol)); /* Calculate arm rol. */ rol = 4 + (rol >> 1); break; } rol += 2; mask >>= 2; if (mask & 0x3) { /* rol by 8. */ imm = (imm << 8) | (imm >> 24); mask = 0xff00; rol = 24; while (1) { if (!(imm & mask)) { /* Rol imm by rol. */ imm = (imm << rol) | (imm >> (32 - rol)); /* Calculate arm rol. */ rol = (rol >> 1) - 8; break; } rol += 2; mask >>= 2; if (mask & 0x3) return 0; } break; } } /* The low 8 bit must be zero. */ SLJIT_ASSERT(!(imm & 0xff)); if (!(imm & 0xff000000)) { imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8); imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); } else if (imm & 0xc0000000) { imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); imm <<= 8; rol += 4; if (!(imm & 0xff000000)) { imm <<= 8; rol += 4; } if (!(imm & 0xf0000000)) { imm <<= 4; rol += 2; } if (!(imm & 0xc0000000)) { imm <<= 2; rol += 1; } if (!(imm & 0x00ffffff)) imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); else return 0; } else { if (!(imm & 0xf0000000)) { imm <<= 4; rol += 2; } if (!(imm & 0xc0000000)) { imm <<= 2; rol += 1; } imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); imm <<= 8; rol += 4; if (!(imm & 0xf0000000)) { imm <<= 4; rol += 2; } if (!(imm & 0xc0000000)) { imm <<= 2; rol += 1; } if (!(imm & 0x00ffffff)) imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); else return 0; } EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2)); return 1; } #endif static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_uw imm) { sljit_uw tmp; #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) if (!(imm & ~0xffff)) return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)); #endif /* Create imm by 1 inst. */ tmp = get_immediate(imm); if (tmp) { EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp)); return SLJIT_SUCCESS; } tmp = get_immediate(~imm); if (tmp) { EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp)); return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) /* Create imm by 2 inst. */ FAIL_IF(generate_int(compiler, reg, imm, 1)); FAIL_IF(generate_int(compiler, reg, ~imm, 0)); /* Load integer. */ return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm); #else return emit_imm(compiler, reg, imm); #endif } /* Can perform an operation using at most 1 instruction. */ static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw) { sljit_uw imm; if (arg & SLJIT_IMM) { imm = get_immediate(argw); if (imm) { if (inp_flags & ARG_TEST) return 1; EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm)); return -1; } imm = get_immediate(~argw); if (imm) { if (inp_flags & ARG_TEST) return 1; EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm)); return -1; } return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } SLJIT_ASSERT(arg & SLJIT_MEM); /* Fast loads/stores. */ if (arg & 0xf) { if (!(arg & 0xf0)) { if (IS_TYPE1_TRANSFER(inp_flags)) { if (argw >= 0 && argw <= 0xfff) { if (inp_flags & ARG_TEST) return 1; EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, argw)); return -1; } if (argw < 0 && argw >= -0xfff) { if (inp_flags & ARG_TEST) return 1; EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, -argw)); return -1; } } else { if (argw >= 0 && argw <= 0xff) { if (inp_flags & ARG_TEST) return 1; EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw))); return -1; } if (argw < 0 && argw >= -0xff) { if (inp_flags & ARG_TEST) return 1; argw = -argw; EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw))); return -1; } } } else if ((argw & 0x3) == 0 || IS_TYPE1_TRANSFER(inp_flags)) { if (inp_flags & ARG_TEST) return 1; EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM((arg >> 4) & 0xf) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7))); return -1; } } return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { /* Immediate caching is not supported as it would be an operation on constant arguments. */ if (arg & SLJIT_IMM) return 0; /* Always a simple operation. */ if (arg & 0xf0) return 0; if (!(arg & 0xf)) { /* Immediate access. */ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) return 1; return 0; } if (argw <= 0xfffff && argw >= -0xfffff) return 0; if (argw == next_argw && (next_arg & SLJIT_MEM)) return 1; if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) return 1; return 0; } #define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \ if (max_delta & 0xf00) \ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \ else \ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm)))); #define TEST_WRITE_BACK() \ if (inp_flags & WRITE_BACK) { \ tmp_r = arg & 0xf; \ if (reg == tmp_r) { \ /* This can only happen for stores */ \ /* since ldr reg, [reg, ...]! has no meaning */ \ SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg))); \ reg = TMP_REG3; \ } \ } /* Emit the necessary instructions. See can_cache above. */ static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { int tmp_r; sljit_w max_delta; sljit_w sign; if (arg & SLJIT_IMM) { SLJIT_ASSERT(inp_flags & LOAD_DATA); return load_immediate(compiler, reg, argw); } SLJIT_ASSERT(arg & SLJIT_MEM); tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3; max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff; if ((arg & 0xf) == SLJIT_UNUSED) { /* Write back is not used. */ if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta)) { if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) { sign = 1; argw = argw - compiler->cache_argw; } else { sign = 0; argw = compiler->cache_argw - argw; } if (max_delta & 0xf00) { EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, argw)); } else { EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, TYPE2_TRANSFER_IMM(argw))); } return SLJIT_SUCCESS; } /* With write back, we can create some sophisticated loads, but it is hard to decide whether we should convert downward (0s) or upward (1s). */ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); compiler->cache_arg = SLJIT_IMM; compiler->cache_argw = argw; tmp_r = TMP_REG3; } FAIL_IF(load_immediate(compiler, tmp_r, argw)); GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0); return SLJIT_SUCCESS; } /* Extended imm addressing for [reg+imm] format. */ sign = (max_delta << 8) | 0xff; if (!(arg & 0xf0) && argw <= sign && argw >= -sign) { TEST_WRITE_BACK(); if (argw >= 0) { sign = 1; } else { sign = 0; argw = -argw; } /* Optimization: add is 0x4, sub is 0x2. Sign is 1 for add and 0 for sub. */ if (max_delta & 0xf00) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 12) | 0xa00)); else EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 8) | 0xc00)); argw &= max_delta; GETPUT_ARG_DATA_TRANSFER(sign, inp_flags & WRITE_BACK, reg, tmp_r, argw); return SLJIT_SUCCESS; } if (arg & 0xf0) { SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00)); if (inp_flags & WRITE_BACK) tmp_r = arg & 0xf; EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7))); EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0))); return SLJIT_SUCCESS; } if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) { SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); argw = argw - compiler->cache_argw; GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, argw); return SLJIT_SUCCESS; } if (compiler->cache_arg == arg && ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta) { SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); argw = compiler->cache_argw - argw; GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, argw); return SLJIT_SUCCESS; } if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) { TEST_WRITE_BACK(); EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); return SLJIT_SUCCESS; } if (argw == next_argw && (next_arg & SLJIT_MEM)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); compiler->cache_arg = SLJIT_IMM; compiler->cache_argw = argw; TEST_WRITE_BACK(); EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); return SLJIT_SUCCESS; } if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & 0xf])); compiler->cache_arg = arg; compiler->cache_argw = argw; GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0); return SLJIT_SUCCESS; } if ((arg & 0xf) == tmp_r) { compiler->cache_arg = SLJIT_IMM; compiler->cache_argw = argw; tmp_r = TMP_REG3; } FAIL_IF(load_immediate(compiler, tmp_r, argw)); EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0))); return SLJIT_SUCCESS; } static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ /* We prefers register and simple consts. */ int dst_r; int src1_r; int src2_r = 0; int sugg_src2_r = TMP_REG2; int flags = GET_FLAGS(op) ? SET_FLAGS : 0; compiler->cache_arg = 0; compiler->cache_argw = 0; /* Destination check. */ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } else if (dst == SLJIT_UNUSED) { if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; dst_r = TMP_REG2; } else { SLJIT_ASSERT(dst & SLJIT_MEM); if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { flags |= FAST_DEST; dst_r = TMP_REG2; } else { flags |= SLOW_DEST; dst_r = 0; } } /* Source 1. */ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) src1_r = src1; else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { flags |= ARGS_SWAPPED; src1_r = src2; src2 = src1; src2w = src1w; } else do { /* do { } while(0) is used because of breaks. */ src1_r = 0; if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) { /* The second check will generate a hit. */ src2_r = get_immediate(src1w); if (src2_r) { flags |= ARGS_SWAPPED; src1 = src2; src1w = src2w; break; } if (inp_flags & ALLOW_INV_IMM) { src2_r = get_immediate(~src1w); if (src2_r) { flags |= ARGS_SWAPPED | INV_IMM; src1 = src2; src1w = src2w; break; } } if (GET_OPCODE(op) == SLJIT_ADD) { src2_r = get_immediate(-src1w); if (src2_r) { /* Note: ARGS_SWAPPED is intentionally not applied! */ src1 = src2; src1w = src2w; op = SLJIT_SUB | GET_ALL_FLAGS(op); break; } } } if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { FAIL_IF(compiler->error); src1_r = TMP_REG1; } } while (0); /* Source 2. */ if (src2_r == 0) { if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { src2_r = src2; flags |= REG_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) dst_r = src2_r; } else do { /* do { } while(0) is used because of breaks. */ if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) { src2_r = get_immediate(src2w); if (src2_r) break; if (inp_flags & ALLOW_INV_IMM) { src2_r = get_immediate(~src2w); if (src2_r) { flags |= INV_IMM; break; } } if (GET_OPCODE(op) == SLJIT_ADD) { src2_r = get_immediate(-src2w); if (src2_r) { op = SLJIT_SUB | GET_ALL_FLAGS(op); flags &= ~ARGS_SWAPPED; break; } } if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) { src2_r = get_immediate(-src2w); if (src2_r) { op = SLJIT_ADD | GET_ALL_FLAGS(op); flags &= ~ARGS_SWAPPED; break; } } } /* src2_r is 0. */ if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { FAIL_IF(compiler->error); src2_r = sugg_src2_r; } } while (0); } /* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero. If they are zero, they must not be registers. */ if (src1_r == 0 && src2_r == 0 && dst_r == 0) { if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); flags |= ARGS_SWAPPED; FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w)); FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw)); } else { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); } src1_r = TMP_REG1; src2_r = TMP_REG2; } else if (src1_r == 0 && src2_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); src1_r = TMP_REG1; } else if (src1_r == 0 && dst_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); src1_r = TMP_REG1; } else if (src2_r == 0 && dst_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); src2_r = sugg_src2_r; } if (dst_r == 0) dst_r = TMP_REG2; if (src1_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); src1_r = TMP_REG1; } if (src2_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); src2_r = sugg_src2_r; } FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); if (flags & (FAST_DEST | SLOW_DEST)) { if (flags & FAST_DEST) FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw)); else FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0)); } return SLJIT_SUCCESS; } #ifdef __cplusplus extern "C" { #endif #if defined(__GNUC__) extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator); extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator); #else #error "Software divmod functions are needed" #endif #ifdef __cplusplus } #endif SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); op = GET_OPCODE(op); switch (op) { case SLJIT_BREAKPOINT: EMIT_INSTRUCTION(BKPT); break; case SLJIT_NOP: EMIT_INSTRUCTION(NOP); break; case SLJIT_UMUL: case SLJIT_SMUL: #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) | (reg_map[SLJIT_TEMPORARY_REG2] << 16) | (reg_map[SLJIT_TEMPORARY_REG1] << 12) | (reg_map[SLJIT_TEMPORARY_REG1] << 8) | reg_map[SLJIT_TEMPORARY_REG2]); #else EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) | (reg_map[SLJIT_TEMPORARY_REG2] << 16) | (reg_map[SLJIT_TEMPORARY_REG1] << 12) | (reg_map[SLJIT_TEMPORARY_REG1] << 8) | reg_map[TMP_REG1]); #endif case SLJIT_UDIV: case SLJIT_SDIV: if (compiler->temporaries >= 3) EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); #else #error "Software divmod functions are needed" #endif if (compiler->temporaries >= 3) return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); return SLJIT_SUCCESS; } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); switch (GET_OPCODE(op)) { case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UB: return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOV_SB: return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOV_UH: return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOV_SH: return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_UI: case SLJIT_MOVU_SI: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UB: return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOVU_SB: return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOVU_UH: return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOVU_SH: return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_NEG: #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw); case SLJIT_CLZ: return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); switch (GET_OPCODE(op)) { case SLJIT_ADD: case SLJIT_ADDC: case SLJIT_SUB: case SLJIT_SUBC: case SLJIT_OR: case SLJIT_XOR: return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); case SLJIT_AND: return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: case SLJIT_LSHR: case SLJIT_ASHR: if (src2 & SLJIT_IMM) { compiler->shift_imm = src2w & 0x1f; return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w); } else { compiler->shift_imm = 0x20; return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); } } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); SLJIT_ASSERT(size == 4); return push_inst(compiler, *(sljit_uw*)instruction); } /* --------------------------------------------------------------------- */ /* Floating point operators */ /* --------------------------------------------------------------------- */ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) /* 0 - no fpu 1 - vfp */ static int arm_fpu_type = -1; static void init_compiler() { if (arm_fpu_type != -1) return; /* TODO: Only the OS can help to determine the correct fpu type. */ arm_fpu_type = 1; } SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { if (arm_fpu_type == -1) init_compiler(); return arm_fpu_type; } #else #define arm_fpu_type 1 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { /* Always available. */ return 1; } #endif #define EMIT_FPU_DATA_TRANSFER(add, load, base, freg, offs) \ (VSTR | ((add) << 23) | ((load) << 20) | (reg_map[base] << 16) | (freg << 12) | (offs)) #define EMIT_FPU_OPERATION(opcode, dst, src1, src2) \ ((opcode) | ((dst) << 12) | (src1) | ((src2) << 16)) static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) { SLJIT_ASSERT(arg & SLJIT_MEM); /* Fast loads and stores. */ if ((arg & 0xf) && !(arg & 0xf0) && (argw & 0x3) == 0) { if (argw >= 0 && argw <= 0x3ff) { EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, arg & 0xf, fpu_reg, argw >> 2)); return SLJIT_SUCCESS; } if (argw < 0 && argw >= -0x3ff) { EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, arg & 0xf, fpu_reg, (-argw) >> 2)); return SLJIT_SUCCESS; } if (argw >= 0 && argw <= 0x3ffff) { SLJIT_ASSERT(get_immediate(argw & 0x3fc00)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00))); argw &= 0x3ff; EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, argw >> 2)); return SLJIT_SUCCESS; } if (argw < 0 && argw >= -0x3ffff) { argw = -argw; SLJIT_ASSERT(get_immediate(argw & 0x3fc00)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00))); argw &= 0x3ff; EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG1, fpu_reg, argw >> 2)); return SLJIT_SUCCESS; } } if (arg & 0xf0) { EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7))); EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, 0)); return SLJIT_SUCCESS; } if (compiler->cache_arg == arg && ((argw - compiler->cache_argw) & 0x3) == 0) { if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= 0x3ff) { EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, (argw - compiler->cache_argw) >> 2)); return SLJIT_SUCCESS; } if (((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= 0x3ff) { EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG3, fpu_reg, (compiler->cache_argw - argw) >> 2)); return SLJIT_SUCCESS; } } compiler->cache_arg = arg; compiler->cache_argw = argw; if (arg & 0xf) { FAIL_IF(load_immediate(compiler, TMP_REG1, argw)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & 0xf, reg_map[TMP_REG1])); } else FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, 0)); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { int dst_freg; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); compiler->cache_arg = 0; compiler->cache_argw = 0; if (GET_OPCODE(op) == SLJIT_FCMP) { if (dst > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); dst = TMP_FREG1; } if (src > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); src = TMP_FREG2; } EMIT_INSTRUCTION(VCMP_F64 | (dst << 12) | src); EMIT_INSTRUCTION(VMRS); return SLJIT_SUCCESS; } dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; if (src > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, dst_freg, 1, src, srcw)); src = dst_freg; } switch (op) { case SLJIT_FMOV: if (src != dst_freg && dst_freg != TMP_FREG1) EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F64, dst_freg, src, 0)); break; case SLJIT_FNEG: EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F64, dst_freg, src, 0)); break; case SLJIT_FABS: EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F64, dst_freg, src, 0)); break; } if (dst_freg == TMP_FREG1) FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { int dst_freg; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; if (src2 > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; } if (src1 > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); src1 = TMP_FREG1; } switch (op) { case SLJIT_FADD: EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F64, dst_freg, src2, src1)); break; case SLJIT_FSUB: EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F64, dst_freg, src2, src1)); break; case SLJIT_FMUL: EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F64, dst_freg, src2, src1)); break; case SLJIT_FDIV: EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F64, dst_freg, src2, src1)); break; } if (dst_freg == TMP_FREG1) FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); else if (dst & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) return compiler->error; EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))); compiler->cache_arg = 0; compiler->cache_argw = 0; return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))); else if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw)) FAIL_IF(compiler->error); else { compiler->cache_arg = 0; compiler->cache_argw = 0; FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2))); } } else if (src & SLJIT_IMM) FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); return push_inst(compiler, BLX | RM(TMP_REG3)); } /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ static sljit_uw get_cc(int type) { switch (type) { case SLJIT_C_EQUAL: case SLJIT_C_MUL_NOT_OVERFLOW: case SLJIT_C_FLOAT_EQUAL: return 0x00000000; case SLJIT_C_NOT_EQUAL: case SLJIT_C_MUL_OVERFLOW: case SLJIT_C_FLOAT_NOT_EQUAL: return 0x10000000; case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: return 0x30000000; case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: return 0x20000000; case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: return 0x80000000; case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: return 0x90000000; case SLJIT_C_SIG_LESS: return 0xb0000000; case SLJIT_C_SIG_GREATER_EQUAL: return 0xa0000000; case SLJIT_C_SIG_GREATER: return 0xc0000000; case SLJIT_C_SIG_LESS_EQUAL: return 0xd0000000; case SLJIT_C_OVERFLOW: case SLJIT_C_FLOAT_NAN: return 0x60000000; case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_FLOAT_NOT_NAN: return 0x70000000; default: /* SLJIT_JUMP */ return 0xe0000000; } } SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { struct sljit_label *label; CHECK_ERROR_PTR(); check_sljit_emit_label(compiler); if (compiler->last_label && compiler->last_label->size == compiler->size) return compiler->last_label; label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); PTR_FAIL_IF(!label); set_label(label, compiler); return label; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; /* In ARM, we don't need to touch the arguments. */ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) if (type >= SLJIT_FAST_CALL) PTR_FAIL_IF(prepare_blx(compiler)); PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0)); if (jump->flags & SLJIT_REWRITABLE_JUMP) { jump->addr = compiler->size; compiler->patches++; } if (type >= SLJIT_FAST_CALL) { jump->flags |= IS_BL; PTR_FAIL_IF(emit_blx(compiler)); } if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) jump->addr = compiler->size; #else if (type >= SLJIT_FAST_CALL) jump->flags |= IS_BL; PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type))); jump->addr = compiler->size; #endif return jump; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { struct sljit_jump *jump; CHECK_ERROR(); check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); /* In ARM, we don't need to touch the arguments. */ if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); jump->u.target = srcw; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) if (type >= SLJIT_FAST_CALL) FAIL_IF(prepare_blx(compiler)); FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0)); if (type >= SLJIT_FAST_CALL) FAIL_IF(emit_blx(compiler)); #else FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1))); #endif jump->addr = compiler->size; } else { if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); SLJIT_ASSERT(src & SLJIT_MEM); FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { int reg; sljit_uw cc; CHECK_ERROR(); check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; cc = get_cc(type); if (GET_OPCODE(op) == SLJIT_OR) { if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ORR_DP, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); if (op & SLJIT_SET_E) return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))); return SLJIT_SUCCESS; } EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 0)); EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return emit_op(compiler, op, ALLOW_IMM, dst, dstw, TMP_REG1, 0, dst, dstw); } reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 0)); EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); if (reg == TMP_REG2) return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; int reg; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); ADJUST_LOCAL_OFFSET(dst, dstw); const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value)); compiler->patches++; #else PTR_FAIL_IF(emit_imm(compiler, reg, init_value)); #endif set_const(const_, compiler); if (reg == TMP_REG2 && dst != SLJIT_UNUSED) if (emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)) return NULL; return const_; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { inline_set_jump_addr(addr, new_addr, 1); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { inline_set_const(addr, new_constant, 1); } pcre-8.31/sljit/sljitNativePPC_common.c0000644000222100022210000017132611736614113015020 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "PowerPC" SLJIT_CPUINFO; } /* Length of an instruction word. Both for ppc-32 and ppc-64. */ typedef sljit_ui sljit_ins; static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) { while (from < to) { #ifdef __GNUC__ asm volatile ( "icbi 0, %0" : : "r"(from) ); #else #error "Must implement icbi" #endif from++; } } #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) #define ZERO_REG (SLJIT_NO_REGISTERS + 4) #define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) #define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* --------------------------------------------------------------------- */ /* Instrucion forms */ /* --------------------------------------------------------------------- */ #define D(d) (reg_map[d] << 21) #define S(s) (reg_map[s] << 21) #define A(a) (reg_map[a] << 16) #define B(b) (reg_map[b] << 11) #define C(c) (reg_map[c] << 6) #define FD(fd) ((fd) << 21) #define FA(fa) ((fa) << 16) #define FB(fb) ((fb) << 11) #define FC(fc) ((fc) << 6) #define IMM(imm) ((imm) & 0xffff) #define CRD(d) ((d) << 21) /* Instruction bit sections. OE and Rc flag (see ALT_SET_FLAGS). */ #define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS)) /* Rc flag (see ALT_SET_FLAGS). */ #define RC(flags) ((flags & ALT_SET_FLAGS) >> 10) #define HI(opcode) ((opcode) << 26) #define LO(opcode) ((opcode) << 1) #define ADD (HI(31) | LO(266)) #define ADDC (HI(31) | LO(10)) #define ADDE (HI(31) | LO(138)) #define ADDI (HI(14)) #define ADDIC (HI(13)) #define ADDIS (HI(15)) #define ADDME (HI(31) | LO(234)) #define AND (HI(31) | LO(28)) #define ANDI (HI(28)) #define ANDIS (HI(29)) #define Bx (HI(18)) #define BCx (HI(16)) #define BCCTR (HI(19) | LO(528) | (3 << 11)) #define BLR (HI(19) | LO(16) | (0x14 << 21)) #define CNTLZD (HI(31) | LO(58)) #define CNTLZW (HI(31) | LO(26)) #define CMP (HI(31) | LO(0)) #define CMPI (HI(11)) #define CMPL (HI(31) | LO(32)) #define CMPLI (HI(10)) #define CROR (HI(19) | LO(449)) #define DIVD (HI(31) | LO(489)) #define DIVDU (HI(31) | LO(457)) #define DIVW (HI(31) | LO(491)) #define DIVWU (HI(31) | LO(459)) #define EXTSB (HI(31) | LO(954)) #define EXTSH (HI(31) | LO(922)) #define EXTSW (HI(31) | LO(986)) #define FABS (HI(63) | LO(264)) #define FADD (HI(63) | LO(21)) #define FCMPU (HI(63) | LO(0)) #define FDIV (HI(63) | LO(18)) #define FMR (HI(63) | LO(72)) #define FMUL (HI(63) | LO(25)) #define FNEG (HI(63) | LO(40)) #define FSUB (HI(63) | LO(20)) #define LD (HI(58) | 0) #define LFD (HI(50)) #define LFDUX (HI(31) | LO(631)) #define LFDX (HI(31) | LO(599)) #define LWZ (HI(32)) #define MFCR (HI(31) | LO(19)) #define MFLR (HI(31) | LO(339) | 0x80000) #define MFXER (HI(31) | LO(339) | 0x10000) #define MTCTR (HI(31) | LO(467) | 0x90000) #define MTLR (HI(31) | LO(467) | 0x80000) #define MTXER (HI(31) | LO(467) | 0x10000) #define MULHD (HI(31) | LO(73)) #define MULHDU (HI(31) | LO(9)) #define MULHW (HI(31) | LO(75)) #define MULHWU (HI(31) | LO(11)) #define MULLD (HI(31) | LO(233)) #define MULLI (HI(7)) #define MULLW (HI(31) | LO(235)) #define NEG (HI(31) | LO(104)) #define NOP (HI(24)) #define NOR (HI(31) | LO(124)) #define OR (HI(31) | LO(444)) #define ORI (HI(24)) #define ORIS (HI(25)) #define RLDICL (HI(30)) #define RLWINM (HI(21)) #define SLD (HI(31) | LO(27)) #define SLW (HI(31) | LO(24)) #define SRAD (HI(31) | LO(794)) #define SRADI (HI(31) | LO(413 << 1)) #define SRAW (HI(31) | LO(792)) #define SRAWI (HI(31) | LO(824)) #define SRD (HI(31) | LO(539)) #define SRW (HI(31) | LO(536)) #define STD (HI(62) | 0) #define STDU (HI(62) | 1) #define STDUX (HI(31) | LO(181)) #define STFD (HI(54)) #define STFDUX (HI(31) | LO(759)) #define STFDX (HI(31) | LO(727)) #define STW (HI(36)) #define STWU (HI(37)) #define STWUX (HI(31) | LO(183)) #define SUBF (HI(31) | LO(40)) #define SUBFC (HI(31) | LO(8)) #define SUBFE (HI(31) | LO(136)) #define SUBFIC (HI(8)) #define XOR (HI(31) | LO(316)) #define XORI (HI(26)) #define XORIS (HI(27)) #define SIMM_MAX (0x7fff) #define SIMM_MIN (-0x8000) #define UIMM_MAX (0xffff) static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31 }; static int push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); *ptr = ins; compiler->size++; return SLJIT_SUCCESS; } static SLJIT_INLINE int optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_w diff; sljit_uw target_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; if (jump->flags & JUMP_ADDR) target_addr = jump->u.target; else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); target_addr = (sljit_uw)(code + jump->u.label->size); } diff = ((sljit_w)target_addr - (sljit_w)(code_ptr)) & ~0x3l; if (jump->flags & UNCOND_B) { if (diff <= 0x01ffffff && diff >= -0x02000000) { jump->flags |= PATCH_B; return 1; } if (target_addr <= 0x03ffffff) { jump->flags |= PATCH_B | ABSOLUTE_B; return 1; } } else { if (diff <= 0x7fff && diff >= -0x8000) { jump->flags |= PATCH_B; return 1; } if (target_addr <= 0xffff) { jump->flags |= PATCH_B | ABSOLUTE_B; return 1; } } return 0; } SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; sljit_ins *code; sljit_ins *code_ptr; sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; sljit_uw addr; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; CHECK_ERROR_PTR(); check_sljit_generate_code(compiler); reverse_buf(compiler); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); #endif code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; code_ptr = code; word_count = 0; label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { *code_ptr = *buf_ptr++; SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); /* These structures are ordered by their address. */ if (label && label->size == word_count) { /* Just recording the address. */ label->addr = (sljit_uw)code_ptr; label->size = code_ptr - code; label = label->next; } if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) jump->addr = (sljit_uw)(code_ptr - 3); #else jump->addr = (sljit_uw)(code_ptr - 6); #endif if (optimize_jump(jump, code_ptr, code)) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) code_ptr[-3] = code_ptr[0]; code_ptr -= 3; #else code_ptr[-6] = code_ptr[0]; code_ptr -= 6; #endif } jump = jump->next; } if (const_ && const_->addr == word_count) { /* Just recording the address. */ const_->addr = (sljit_uw)code_ptr; const_ = const_->next; } code_ptr ++; word_count ++; } while (buf_ptr < buf_end); buf = buf->next; } while (buf); if (label && label->size == word_count) { label->addr = (sljit_uw)code_ptr; label->size = code_ptr - code; label = label->next; } SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) SLJIT_ASSERT(code_ptr - code <= (int)compiler->size - ((compiler->size & 0x1) ? 3 : 2)); #else SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); #endif jump = compiler->jumps; while (jump) { do { addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; buf_ptr = (sljit_ins*)jump->addr; if (jump->flags & PATCH_B) { if (jump->flags & UNCOND_B) { if (!(jump->flags & ABSOLUTE_B)) { addr = addr - jump->addr; SLJIT_ASSERT((sljit_w)addr <= 0x01ffffff && (sljit_w)addr >= -0x02000000); *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); } else { SLJIT_ASSERT(addr <= 0x03ffffff); *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1); } } else { if (!(jump->flags & ABSOLUTE_B)) { addr = addr - jump->addr; SLJIT_ASSERT((sljit_w)addr <= 0x7fff && (sljit_w)addr >= -0x8000); *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); } else { addr = addr & ~0x3l; SLJIT_ASSERT(addr <= 0xffff); *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001); } } break; } /* Set the fields of immediate loads. */ #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); #else buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); #endif } while (0); jump = jump->next; } SLJIT_CACHE_FLUSH(code, code_ptr); compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = compiler->size * sizeof(sljit_ins); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (((sljit_w)code_ptr) & 0x4) code_ptr++; sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_w)code, sljit_generate_code); return code_ptr; #else return code; #endif } /* inp_flags: */ /* Creates an index in data_transfer_insts array. */ #define WORD_DATA 0x00 #define BYTE_DATA 0x01 #define HALF_DATA 0x02 #define INT_DATA 0x03 #define SIGNED_DATA 0x04 #define LOAD_DATA 0x08 #define WRITE_BACK 0x10 #define INDEXED 0x20 #define MEM_MASK 0x3f /* Other inp_flags. */ #define ARG_TEST 0x000100 /* Integer opertion and set flags -> requires exts on 64 bit systems. */ #define ALT_SIGN_EXT 0x000200 /* This flag affects the RC() and OERC() macros. */ #define ALT_SET_FLAGS 0x000400 #define ALT_FORM1 0x010000 #define ALT_FORM2 0x020000 #define ALT_FORM3 0x040000 #define ALT_FORM4 0x080000 #define ALT_FORM5 0x100000 #define ALT_FORM6 0x200000 /* Source and destination is register. */ #define REG_DEST 0x000001 #define REG1_SOURCE 0x000002 #define REG2_SOURCE 0x000004 /* getput_arg_fast returned true. */ #define FAST_DEST 0x000008 /* Multiple instructions are required. */ #define SLOW_DEST 0x000010 /* ALT_SIGN_EXT 0x000200 ALT_SET_FLAGS 0x000400 ALT_FORM1 0x010000 ... ALT_FORM6 0x200000 */ #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #include "sljitNativePPC_32.c" #else #include "sljitNativePPC_64.c" #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #define STACK_STORE STW #define STACK_LOAD LWZ #else #define STACK_STORE STD #define STACK_LOAD LD #endif static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w); SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { CHECK_ERROR(); check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif FAIL_IF(push_inst(compiler, MFLR | D(0))); FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(int)(sizeof(sljit_w))) )); if (saveds >= 1) FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (int)(sizeof(sljit_w))) )); if (saveds >= 2) FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (int)(sizeof(sljit_w))) )); if (saveds >= 3) FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (int)(sizeof(sljit_w))) )); if (saveds >= 4) FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (int)(sizeof(sljit_w))) )); if (saveds >= 5) FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (int)(sizeof(sljit_w))) )); FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_w)) )); FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0)); if (args >= 1) FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_TEMPORARY_REG1))); if (args >= 2) FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_TEMPORARY_REG2))); if (args >= 3) FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_TEMPORARY_REG3))); #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) compiler->local_size = (1 + saveds + 2) * sizeof(sljit_w) + local_size; #else compiler->local_size = (1 + saveds + 7 + 8) * sizeof(sljit_w) + local_size; #endif compiler->local_size = (compiler->local_size + 15) & ~0xf; #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) if (compiler->local_size <= SIMM_MAX) FAIL_IF(push_inst(compiler, STWU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size))); else { FAIL_IF(load_immediate(compiler, 0, -compiler->local_size)); FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); } #else if (compiler->local_size <= SIMM_MAX) FAIL_IF(push_inst(compiler, STDU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size))); else { FAIL_IF(load_immediate(compiler, 0, -compiler->local_size)); FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); } #endif return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { CHECK_ERROR_VOID(); check_sljit_set_context(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) compiler->local_size = (1 + saveds + 2) * sizeof(sljit_w) + local_size; #else compiler->local_size = (1 + saveds + 7 + 8) * sizeof(sljit_w) + local_size; #endif compiler->local_size = (compiler->local_size + 15) & ~0xf; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); if (compiler->local_size <= SIMM_MAX) FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(compiler->local_size))); else { FAIL_IF(load_immediate(compiler, 0, compiler->local_size)); FAIL_IF(push_inst(compiler, ADD | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); } FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_w)))); if (compiler->saveds >= 5) FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 4) FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 3) FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 2) FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 1) FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (int)(sizeof(sljit_w))) )); FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(int)(sizeof(sljit_w))) )); FAIL_IF(push_inst(compiler, MTLR | S(0))); FAIL_IF(push_inst(compiler, BLR)); return SLJIT_SUCCESS; } #undef STACK_STORE #undef STACK_LOAD /* --------------------------------------------------------------------- */ /* Operators */ /* --------------------------------------------------------------------- */ /* i/x - immediate/indexed form n/w - no write-back / write-back (1 bit) s/l - store/load (1 bit) u/s - signed/unsigned (1 bit) w/b/h/i - word/byte/half/int allowed (2 bit) It contans 32 items, but not all are different. */ /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */ #define ADDR_MODE2 0x10000 /* 64-bit only: there is no lwau instruction. */ #define UPDATE_REQ 0x20000 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #define ARCH_DEPEND(a, b) a #define GET_INST_CODE(inst) (inst) #else #define ARCH_DEPEND(a, b) b #define GET_INST_CODE(index) ((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) #endif static SLJIT_CONST sljit_ins data_transfer_insts[64] = { /* No write-back. */ /* i n s u w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), /* i n s u b */ HI(38) /* stb */, /* i n s u h */ HI(44) /* sth*/, /* i n s u i */ HI(36) /* stw */, /* i n s s w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), /* i n s s b */ HI(38) /* stb */, /* i n s s h */ HI(44) /* sth*/, /* i n s s i */ HI(36) /* stw */, /* i n l u w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), /* i n l u b */ HI(34) /* lbz */, /* i n l u h */ HI(40) /* lhz */, /* i n l u i */ HI(32) /* lwz */, /* i n l s w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), /* i n l s b */ HI(34) /* lbz */ /* EXTS_REQ */, /* i n l s h */ HI(42) /* lha */, /* i n l s i */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */), /* Write-back. */ /* i w s u w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), /* i w s u b */ HI(39) /* stbu */, /* i w s u h */ HI(45) /* sthu */, /* i w s u i */ HI(37) /* stwu */, /* i w s s w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), /* i w s s b */ HI(39) /* stbu */, /* i w s s h */ HI(45) /* sthu */, /* i w s s i */ HI(37) /* stwu */, /* i w l u w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), /* i w l u b */ HI(35) /* lbzu */, /* i w l u h */ HI(41) /* lhzu */, /* i w l u i */ HI(33) /* lwzu */, /* i w l s w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), /* i w l s b */ HI(35) /* lbzu */ /* EXTS_REQ */, /* i w l s h */ HI(43) /* lhau */, /* i w l s i */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */), /* ---------- */ /* Indexed */ /* ---------- */ /* No write-back. */ /* x n s u w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), /* x n s u b */ HI(31) | LO(215) /* stbx */, /* x n s u h */ HI(31) | LO(407) /* sthx */, /* x n s u i */ HI(31) | LO(151) /* stwx */, /* x n s s w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), /* x n s s b */ HI(31) | LO(215) /* stbx */, /* x n s s h */ HI(31) | LO(407) /* sthx */, /* x n s s i */ HI(31) | LO(151) /* stwx */, /* x n l u w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), /* x n l u b */ HI(31) | LO(87) /* lbzx */, /* x n l u h */ HI(31) | LO(279) /* lhzx */, /* x n l u i */ HI(31) | LO(23) /* lwzx */, /* x n l s w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), /* x n l s b */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, /* x n l s h */ HI(31) | LO(343) /* lhax */, /* x n l s i */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), /* Write-back. */ /* x w s u w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), /* x w s u b */ HI(31) | LO(247) /* stbux */, /* x w s u h */ HI(31) | LO(439) /* sthux */, /* x w s u i */ HI(31) | LO(183) /* stwux */, /* x w s s w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), /* x w s s b */ HI(31) | LO(247) /* stbux */, /* x w s s h */ HI(31) | LO(439) /* sthux */, /* x w s s i */ HI(31) | LO(183) /* stwux */, /* x w l u w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), /* x w l u b */ HI(31) | LO(119) /* lbzux */, /* x w l u h */ HI(31) | LO(311) /* lhzux */, /* x w l u i */ HI(31) | LO(55) /* lwzux */, /* x w l s w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), /* x w l s b */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, /* x w l s h */ HI(31) | LO(375) /* lhaux */, /* x w l s i */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */) }; #undef ARCH_DEPEND /* Simple cases, (no caching is required). */ static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw) { sljit_ins inst; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) int tmp_reg; #endif SLJIT_ASSERT(arg & SLJIT_MEM); if (!(arg & 0xf)) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) if (argw <= SIMM_MAX && argw >= SIMM_MIN) { if (inp_flags & ARG_TEST) return 1; inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw)); return -1; } #else inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; if (argw <= SIMM_MAX && argw >= SIMM_MIN && (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) { if (inp_flags & ARG_TEST) return 1; push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw)); return -1; } #endif return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } if (!(arg & 0xf0)) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) if (argw <= SIMM_MAX && argw >= SIMM_MIN) { if (inp_flags & ARG_TEST) return 1; inst = data_transfer_insts[inp_flags & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw)); return -1; } #else inst = data_transfer_insts[inp_flags & MEM_MASK]; if (argw <= SIMM_MAX && argw >= SIMM_MIN && (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) { if (inp_flags & ARG_TEST) return 1; if ((inp_flags & WRITE_BACK) && (inst & UPDATE_REQ)) { tmp_reg = (inp_flags & LOAD_DATA) ? (arg & 0xf) : TMP_REG3; if (push_inst(compiler, ADDI | D(tmp_reg) | A(arg & 0xf) | IMM(argw))) return -1; arg = tmp_reg | SLJIT_MEM; argw = 0; } push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw)); return -1; } #endif } else if (!(argw & 0x3)) { if (inp_flags & ARG_TEST) return 1; inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); return -1; } return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } /* See getput_arg below. Note: can_cache is called only for binary operators. Those operator always uses word arguments without write back. */ static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { SLJIT_ASSERT(arg & SLJIT_MEM); SLJIT_ASSERT(next_arg & SLJIT_MEM); if (!(arg & 0xf)) { if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) return 1; return 0; } if (arg & 0xf0) return 0; if (argw <= SIMM_MAX && argw >= SIMM_MIN) { if (arg == next_arg && (next_argw >= SIMM_MAX && next_argw <= SIMM_MIN)) return 1; } if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) return 1; return 0; } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define ADJUST_CACHED_IMM(imm) \ if ((inst & ADDR_MODE2) && (imm & 0x3)) { \ /* Adjust cached value. Fortunately this is really a rare case */ \ compiler->cache_argw += imm & 0x3; \ FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \ imm &= ~0x3; \ } #else #define ADJUST_CACHED_IMM(imm) #endif /* Emit the necessary instructions. See can_cache above. */ static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { int tmp_r; sljit_ins inst; SLJIT_ASSERT(arg & SLJIT_MEM); tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3; if ((arg & 0xf) == tmp_r) { /* Special case for "mov reg, [reg, ... ]". Caching would not happen anyway. */ tmp_r = TMP_REG3; compiler->cache_arg = 0; compiler->cache_argw = 0; } if (!(arg & 0xf)) { inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= SIMM_MAX || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= SIMM_MAX)) { argw = argw - compiler->cache_argw; ADJUST_CACHED_IMM(argw); SLJIT_ASSERT(!(inst & UPDATE_REQ)); return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw)); } if ((next_arg & SLJIT_MEM) && (argw - next_argw <= SIMM_MAX || next_argw - argw <= SIMM_MAX)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); compiler->cache_arg = SLJIT_IMM; compiler->cache_argw = argw; tmp_r = TMP_REG3; } FAIL_IF(load_immediate(compiler, tmp_r, argw)); return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(tmp_r)); } if (SLJIT_UNLIKELY(arg & 0xf0)) { argw &= 0x3; /* Otherwise getput_arg_fast would capture it. */ SLJIT_ASSERT(argw); #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); #else FAIL_IF(push_inst(compiler, RLDI(tmp_r, (arg >> 4) & 0xf, argw, 63 - argw, 1))); #endif inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r)); } inst = data_transfer_insts[inp_flags & MEM_MASK]; if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw <= SIMM_MAX || (sljit_uw)compiler->cache_argw - (sljit_uw)argw <= SIMM_MAX)) { SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); argw = argw - compiler->cache_argw; ADJUST_CACHED_IMM(argw); return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw)); } if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) { inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3)); } if (argw == next_argw && (next_arg & SLJIT_MEM)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); compiler->cache_arg = SLJIT_IMM; compiler->cache_argw = argw; inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3)); } if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & 0xf))); compiler->cache_arg = arg; compiler->cache_argw = argw; return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3)); } /* Get the indexed version instead of the normal one. */ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); FAIL_IF(load_immediate(compiler, tmp_r, argw)); return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r)); } static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ int dst_r; int src1_r; int src2_r; int sugg_src2_r = TMP_REG2; int flags = inp_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); compiler->cache_arg = 0; compiler->cache_argw = 0; /* Destination check. */ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= ZERO_REG) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } else if (dst == SLJIT_UNUSED) { if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; dst_r = TMP_REG2; } else { SLJIT_ASSERT(dst & SLJIT_MEM); if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { flags |= FAST_DEST; dst_r = TMP_REG2; } else { flags |= SLOW_DEST; dst_r = 0; } } /* Source 1. */ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= ZERO_REG) { src1_r = src1; flags |= REG1_SOURCE; } else if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if ((inp_flags & 0x3) == INT_DATA) { if (inp_flags & SIGNED_DATA) src1w = (signed int)src1w; else src1w = (unsigned int)src1w; } #endif FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); src1_r = TMP_REG1; } else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { FAIL_IF(compiler->error); src1_r = TMP_REG1; } else src1_r = 0; /* Source 2. */ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= ZERO_REG) { src2_r = src2; flags |= REG2_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if ((inp_flags & 0x3) == INT_DATA) { if (inp_flags & SIGNED_DATA) src2w = (signed int)src2w; else src2w = (unsigned int)src2w; } #endif FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); src2_r = sugg_src2_r; } else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { FAIL_IF(compiler->error); src2_r = sugg_src2_r; } else src2_r = 0; /* src1_r, src2_r and dst_r can be zero (=unprocessed). All arguments are complex addressing modes, and it is a binary operator. */ if (src1_r == 0 && src2_r == 0 && dst_r == 0) { if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); } else { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); } src1_r = TMP_REG1; src2_r = TMP_REG2; } else if (src1_r == 0 && src2_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); src1_r = TMP_REG1; } else if (src1_r == 0 && dst_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); src1_r = TMP_REG1; } else if (src2_r == 0 && dst_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); src2_r = sugg_src2_r; } if (dst_r == 0) dst_r = TMP_REG2; if (src1_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); src1_r = TMP_REG1; } if (src2_r == 0) { FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); src2_r = sugg_src2_r; } FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); if (flags & (FAST_DEST | SLOW_DEST)) { if (flags & FAST_DEST) FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw)); else FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0)); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); switch (GET_OPCODE(op)) { case SLJIT_BREAKPOINT: case SLJIT_NOP: return push_inst(compiler, NOP); break; case SLJIT_UMUL: case SLJIT_SMUL: FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); #else FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); #endif case SLJIT_UDIV: case SLJIT_SDIV: FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) { FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); } FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); #else FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); #endif } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); if ((src & SLJIT_IMM) && srcw == 0) src = ZERO_REG; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) { inp_flags |= INT_DATA | SIGNED_DATA; if (src & SLJIT_IMM) srcw = (int)srcw; } #endif if (op & SLJIT_SET_O) FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); switch (GET_OPCODE(op)) { case SLJIT_MOV: return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UI: return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_SI: return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UB: return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOV_SB: return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOV_UH: return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOV_SH: return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_MOVU: return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UI: return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_SI: return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UB: return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOVU_SB: return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOVU_UH: return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOVU_SH: return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, SLJIT_NOT, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_NEG: return emit_op(compiler, SLJIT_NEG, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_CLZ: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) return emit_op(compiler, SLJIT_CLZ, inp_flags | (!(op & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); #else return emit_op(compiler, SLJIT_CLZ, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); #endif } return SLJIT_SUCCESS; } #define TEST_SL_IMM(src, srcw) \ (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) #define TEST_UL_IMM(src, srcw) \ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff)) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define TEST_SH_IMM(src, srcw) \ (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= SLJIT_W(0x7fffffff) && (srcw) >= SLJIT_W(-0x80000000)) #else #define TEST_SH_IMM(src, srcw) \ (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) #endif #define TEST_UH_IMM(src, srcw) \ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000)) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define TEST_ADD_IMM(src, srcw) \ (((src) & SLJIT_IMM) && (srcw) <= SLJIT_W(0x7fff7fff) && (srcw) >= SLJIT_W(-0x80000000)) #else #define TEST_ADD_IMM(src, srcw) \ ((src) & SLJIT_IMM) #endif #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define TEST_UI_IMM(src, srcw) \ (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff)) #else #define TEST_UI_IMM(src, srcw) \ ((src) & SLJIT_IMM) #endif SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); if ((src1 & SLJIT_IMM) && src1w == 0) src1 = ZERO_REG; if ((src2 & SLJIT_IMM) && src2w == 0) src2 = ZERO_REG; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) { inp_flags |= INT_DATA | SIGNED_DATA; if (src1 & SLJIT_IMM) src1w = (src1w << 32) >> 32; if (src2 & SLJIT_IMM) src2w = (src2w << 32) >> 32; if (GET_FLAGS(op)) inp_flags |= ALT_SIGN_EXT; } #endif if (op & SLJIT_SET_O) FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); switch (GET_OPCODE(op)) { case SLJIT_ADD: if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } if (TEST_SH_IMM(src2, src2w)) { compiler->imm = (src2w >> 16) & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SH_IMM(src1, src1w)) { compiler->imm = (src1w >> 16) & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); } /* Range between -1 and -32768 is covered above. */ if (TEST_ADD_IMM(src2, src2w)) { compiler->imm = src2w & 0xffffffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_ADD_IMM(src1, src1w)) { compiler->imm = src1w & 0xffffffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0); } } if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); } } return emit_op(compiler, SLJIT_ADD, inp_flags, dst, dstw, src1, src1w, src2, src2w); case SLJIT_ADDC: return emit_op(compiler, SLJIT_ADDC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUB: if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { if (TEST_SL_IMM(src2, -src2w)) { compiler->imm = (-src2w) & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } if (TEST_SH_IMM(src2, -src2w)) { compiler->imm = ((-src2w) >> 16) & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } /* Range between -1 and -32768 is covered above. */ if (TEST_ADD_IMM(src2, -src2w)) { compiler->imm = -src2w & 0xffffffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); } } if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) { if (!(op & SLJIT_SET_U)) { /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); } } if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) { /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ if (TEST_UL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w); } if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) { compiler->imm = src2w; return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } return emit_op(compiler, SLJIT_SUB, inp_flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); } if (!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))) { if (TEST_SL_IMM(src2, -src2w)) { compiler->imm = (-src2w) & 0xffff; return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } } /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ return emit_op(compiler, SLJIT_SUB, inp_flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: return emit_op(compiler, SLJIT_SUBC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) inp_flags |= ALT_FORM2; #endif if (!GET_FLAGS(op)) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } } return emit_op(compiler, SLJIT_MUL, inp_flags, dst, dstw, src1, src1w, src2, src2w); case SLJIT_AND: case SLJIT_OR: case SLJIT_XOR: /* Commutative unsigned operations. */ if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { if (TEST_UL_IMM(src2, src2w)) { compiler->imm = src2w; return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_UL_IMM(src1, src1w)) { compiler->imm = src1w; return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } if (TEST_UH_IMM(src2, src2w)) { compiler->imm = (src2w >> 16) & 0xffff; return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_UH_IMM(src1, src1w)) { compiler->imm = (src1w >> 16) & 0xffff; return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); } } if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) { if (TEST_UI_IMM(src2, src2w)) { compiler->imm = src2w; return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_UI_IMM(src1, src1w)) { compiler->imm = src1w; return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); } } return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: case SLJIT_LSHR: case SLJIT_ASHR: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) inp_flags |= ALT_FORM2; #endif if (src2 & SLJIT_IMM) { compiler->imm = src2w; return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); SLJIT_ASSERT(size == 4); return push_inst(compiler, *(sljit_ins*)instruction); } /* --------------------------------------------------------------------- */ /* Floating point operators */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { /* Always available. */ return 1; } static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) { SLJIT_ASSERT(arg & SLJIT_MEM); /* Fast loads and stores. */ if (!(arg & 0xf0)) { /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */ if (argw <= SIMM_MAX && argw >= SIMM_MIN) return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(arg & 0xf) | IMM(argw)); } if (arg & 0xf0) { argw &= 0x3; if (argw) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(TMP_REG2) | (argw << 11) | ((31 - argw) << 1))); #else FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, (arg >> 4) & 0xf, argw, 63 - argw, 1))); #endif return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B(TMP_REG2)); } return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); } /* Use cache. */ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(TMP_REG3) | IMM(argw - compiler->cache_argw)); /* Put value to cache. */ compiler->cache_arg = arg; compiler->cache_argw = argw; FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); if (!(arg & 0xf)) return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(0) | B(TMP_REG3)); return push_inst(compiler, (load ? LFDUX : STFDUX) | FD(fpu_reg) | A(TMP_REG3) | B(arg & 0xf)); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { int dst_fr; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); compiler->cache_arg = 0; compiler->cache_argw = 0; if (GET_OPCODE(op) == SLJIT_FCMP) { if (dst > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); dst = TMP_FREG1; } if (src > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); src = TMP_FREG2; } return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src)); } dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; if (src > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw)); src = dst_fr; } switch (op) { case SLJIT_FMOV: if (src != dst_fr && dst_fr != TMP_FREG1) FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src))); break; case SLJIT_FNEG: FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src))); break; case SLJIT_FABS: FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src))); break; } if (dst_fr == TMP_FREG1) FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { int dst_fr; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; if (src2 > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; } if (src1 > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); src1 = TMP_FREG1; } switch (op) { case SLJIT_FADD: FAIL_IF(push_inst(compiler, FADD | FD(dst_fr) | FA(src1) | FB(src2))); break; case SLJIT_FSUB: FAIL_IF(push_inst(compiler, FSUB | FD(dst_fr) | FA(src1) | FB(src2))); break; case SLJIT_FMUL: FAIL_IF(push_inst(compiler, FMUL | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); break; case SLJIT_FDIV: FAIL_IF(push_inst(compiler, FDIV | FD(dst_fr) | FA(src1) | FB(src2))); break; } if (dst_fr == TMP_FREG1) FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst(compiler, MFLR | D(dst)); else if (dst & SLJIT_MEM) { FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) FAIL_IF(push_inst(compiler, MTLR | S(src))); else { if (src & SLJIT_MEM) FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); else if (src & SLJIT_IMM) FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2))); } return push_inst(compiler, BLR); } /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { struct sljit_label *label; CHECK_ERROR_PTR(); check_sljit_emit_label(compiler); if (compiler->last_label && compiler->last_label->size == compiler->size) return compiler->last_label; label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); PTR_FAIL_IF(!label); set_label(label, compiler); return label; } static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, int type) { switch (type) { case SLJIT_C_EQUAL: return (12 << 21) | (2 << 16); case SLJIT_C_NOT_EQUAL: return (4 << 21) | (2 << 16); case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: return (12 << 21) | ((4 + 0) << 16); case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: return (4 << 21) | ((4 + 0) << 16); case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: return (12 << 21) | ((4 + 1) << 16); case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: return (4 << 21) | ((4 + 1) << 16); case SLJIT_C_SIG_LESS: return (12 << 21) | (0 << 16); case SLJIT_C_SIG_GREATER_EQUAL: return (4 << 21) | (0 << 16); case SLJIT_C_SIG_GREATER: return (12 << 21) | (1 << 16); case SLJIT_C_SIG_LESS_EQUAL: return (4 << 21) | (1 << 16); case SLJIT_C_OVERFLOW: case SLJIT_C_MUL_OVERFLOW: return (12 << 21) | (3 << 16); case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_MUL_NOT_OVERFLOW: return (4 << 21) | (3 << 16); case SLJIT_C_FLOAT_EQUAL: return (12 << 21) | ((4 + 2) << 16); case SLJIT_C_FLOAT_NOT_EQUAL: return (4 << 21) | ((4 + 2) << 16); case SLJIT_C_FLOAT_NAN: return (12 << 21) | ((4 + 3) << 16); case SLJIT_C_FLOAT_NOT_NAN: return (4 << 21) | ((4 + 3) << 16); default: SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); return (20 << 21); } } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; sljit_ins bo_bi_flags; CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); bo_bi_flags = get_bo_bi_flags(compiler, type & 0xff); if (!bo_bi_flags) return NULL; jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; /* In PPC, we don't need to touch the arguments. */ if (type >= SLJIT_JUMP) jump->flags |= UNCOND_B; PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0)); PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_REG1))); jump->addr = compiler->size; PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0))); return jump; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { sljit_ins bo_bi_flags; struct sljit_jump *jump = NULL; int src_r; CHECK_ERROR(); check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); bo_bi_flags = get_bo_bi_flags(compiler, type); FAIL_IF(!bo_bi_flags); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) src_r = src; else if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); set_jump(jump, compiler, JUMP_ADDR | UNCOND_B); jump->u.target = srcw; FAIL_IF(emit_const(compiler, TMP_REG2, 0)); src_r = TMP_REG2; } else { FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); src_r = TMP_REG2; } FAIL_IF(push_inst(compiler, MTCTR | S(src_r))); if (jump) jump->addr = compiler->size; return push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)); } /* Get a bit from CR, all other bits are zeroed. */ #define GET_CR_BIT(bit, dst) \ FAIL_IF(push_inst(compiler, MFCR | D(dst))); \ FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1))); #define INVERT_BIT(dst) \ FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { int reg; CHECK_ERROR(); check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; switch (type) { case SLJIT_C_EQUAL: GET_CR_BIT(2, reg); break; case SLJIT_C_NOT_EQUAL: GET_CR_BIT(2, reg); INVERT_BIT(reg); break; case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: GET_CR_BIT(4 + 0, reg); break; case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: GET_CR_BIT(4 + 0, reg); INVERT_BIT(reg); break; case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: GET_CR_BIT(4 + 1, reg); break; case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: GET_CR_BIT(4 + 1, reg); INVERT_BIT(reg); break; case SLJIT_C_SIG_LESS: GET_CR_BIT(0, reg); break; case SLJIT_C_SIG_GREATER_EQUAL: GET_CR_BIT(0, reg); INVERT_BIT(reg); break; case SLJIT_C_SIG_GREATER: GET_CR_BIT(1, reg); break; case SLJIT_C_SIG_LESS_EQUAL: GET_CR_BIT(1, reg); INVERT_BIT(reg); break; case SLJIT_C_OVERFLOW: case SLJIT_C_MUL_OVERFLOW: GET_CR_BIT(3, reg); break; case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_MUL_NOT_OVERFLOW: GET_CR_BIT(3, reg); INVERT_BIT(reg); break; case SLJIT_C_FLOAT_EQUAL: GET_CR_BIT(4 + 2, reg); break; case SLJIT_C_FLOAT_NOT_EQUAL: GET_CR_BIT(4 + 2, reg); INVERT_BIT(reg); break; case SLJIT_C_FLOAT_NAN: GET_CR_BIT(4 + 3, reg); break; case SLJIT_C_FLOAT_NOT_NAN: GET_CR_BIT(4 + 3, reg); INVERT_BIT(reg); break; default: SLJIT_ASSERT_STOP(); break; } if (GET_OPCODE(op) == SLJIT_OR) return emit_op(compiler, GET_OPCODE(op), GET_FLAGS(op) ? ALT_SET_FLAGS : 0, dst, dstw, dst, dstw, TMP_REG2, 0); if (reg == TMP_REG2) return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; int reg; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); ADJUST_LOCAL_OFFSET(dst, dstw); const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); set_const(const_, compiler); reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); return const_; } pcre-8.31/sljit/sljitExecAllocator.c0000644000222100022210000002204511676645225014410 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file contains a simple executable memory allocator It is assumed, that executable code blocks are usually medium (or sometimes large) memory blocks, and the allocator is not too frequently called (less optimized than other allocators). Thus, using it as a generic allocator is not suggested. How does it work: Memory is allocated in continuous memory areas called chunks by alloc_chunk() Chunk format: [ block ][ block ] ... [ block ][ block terminator ] All blocks and the block terminator is started with block_header. The block header contains the size of the previous and the next block. These sizes can also contain special values. Block size: 0 - The block is a free_block, with a different size member. 1 - The block is a block terminator. n - The block is used at the moment, and the value contains its size. Previous block size: 0 - This is the first block of the memory chunk. n - The size of the previous block. Using these size values we can go forward or backward on the block chain. The unused blocks are stored in a chain list pointed by free_blocks. This list is useful if we need to find a suitable memory area when the allocator is called. When a block is freed, the new free block is connected to its adjacent free blocks if possible. [ free block ][ used block ][ free block ] and "used block" is freed, the three blocks are connected together: [ one big free block ] */ /* --------------------------------------------------------------------- */ /* System (OS) functions */ /* --------------------------------------------------------------------- */ /* 64 KByte. */ #define CHUNK_SIZE 0x10000 /* alloc_chunk / free_chunk : * allocate executable system memory chunks * the size is always divisible by CHUNK_SIZE allocator_grab_lock / allocator_release_lock : * make the allocator thread safe * can be empty if the OS (or the application) does not support threading * only the allocator requires this lock, sljit is fully thread safe as it only uses local variables */ #ifdef _WIN32 static SLJIT_INLINE void* alloc_chunk(sljit_uw size) { return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); } static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) { SLJIT_UNUSED_ARG(size); VirtualFree(chunk, 0, MEM_RELEASE); } #else #include static SLJIT_INLINE void* alloc_chunk(sljit_uw size) { void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); return (retval != MAP_FAILED) ? retval : NULL; } static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) { munmap(chunk, size); } #endif /* --------------------------------------------------------------------- */ /* Common functions */ /* --------------------------------------------------------------------- */ #define CHUNK_MASK (~(CHUNK_SIZE - 1)) struct block_header { sljit_uw size; sljit_uw prev_size; }; struct free_block { struct block_header header; struct free_block *next; struct free_block *prev; sljit_uw size; }; #define AS_BLOCK_HEADER(base, offset) \ ((struct block_header*)(((sljit_ub*)base) + offset)) #define AS_FREE_BLOCK(base, offset) \ ((struct free_block*)(((sljit_ub*)base) + offset)) #define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header))) #define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7) static struct free_block* free_blocks; static sljit_uw allocated_size; static sljit_uw total_size; static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size) { free_block->header.size = 0; free_block->size = size; free_block->next = free_blocks; free_block->prev = 0; if (free_blocks) free_blocks->prev = free_block; free_blocks = free_block; } static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block) { if (free_block->next) free_block->next->prev = free_block->prev; if (free_block->prev) free_block->prev->next = free_block->next; else { SLJIT_ASSERT(free_blocks == free_block); free_blocks = free_block->next; } } SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) { struct block_header *header; struct block_header *next_header; struct free_block *free_block; sljit_uw chunk_size; allocator_grab_lock(); if (size < sizeof(struct free_block)) size = sizeof(struct free_block); size = ALIGN_SIZE(size); free_block = free_blocks; while (free_block) { if (free_block->size >= size) { chunk_size = free_block->size; if (chunk_size > size + 64) { /* We just cut a block from the end of the free block. */ chunk_size -= size; free_block->size = chunk_size; header = AS_BLOCK_HEADER(free_block, chunk_size); header->prev_size = chunk_size; AS_BLOCK_HEADER(header, size)->prev_size = size; } else { sljit_remove_free_block(free_block); header = (struct block_header*)free_block; size = chunk_size; } allocated_size += size; header->size = size; allocator_release_lock(); return MEM_START(header); } free_block = free_block->next; } chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK; header = (struct block_header*)alloc_chunk(chunk_size); PTR_FAIL_IF(!header); chunk_size -= sizeof(struct block_header); total_size += chunk_size; header->prev_size = 0; if (chunk_size > size + 64) { /* Cut the allocated space into a free and a used block. */ allocated_size += size; header->size = size; chunk_size -= size; free_block = AS_FREE_BLOCK(header, size); free_block->header.prev_size = size; sljit_insert_free_block(free_block, chunk_size); next_header = AS_BLOCK_HEADER(free_block, chunk_size); } else { /* All space belongs to this allocation. */ allocated_size += chunk_size; header->size = chunk_size; next_header = AS_BLOCK_HEADER(header, chunk_size); } next_header->size = 1; next_header->prev_size = chunk_size; allocator_release_lock(); return MEM_START(header); } SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) { struct block_header *header; struct free_block* free_block; allocator_grab_lock(); header = AS_BLOCK_HEADER(ptr, -(sljit_w)sizeof(struct block_header)); allocated_size -= header->size; /* Connecting free blocks together if possible. */ /* If header->prev_size == 0, free_block will equal to header. In this case, free_block->header.size will be > 0. */ free_block = AS_FREE_BLOCK(header, -(sljit_w)header->prev_size); if (SLJIT_UNLIKELY(!free_block->header.size)) { free_block->size += header->size; header = AS_BLOCK_HEADER(free_block, free_block->size); header->prev_size = free_block->size; } else { free_block = (struct free_block*)header; sljit_insert_free_block(free_block, header->size); } header = AS_BLOCK_HEADER(free_block, free_block->size); if (SLJIT_UNLIKELY(!header->size)) { free_block->size += ((struct free_block*)header)->size; sljit_remove_free_block((struct free_block*)header); header = AS_BLOCK_HEADER(free_block, free_block->size); header->prev_size = free_block->size; } /* The whole chunk is free. */ if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) { /* If this block is freed, we still have (allocated_size / 2) free space. */ if (total_size - free_block->size > (allocated_size * 3 / 2)) { total_size -= free_block->size; sljit_remove_free_block(free_block); free_chunk(free_block, free_block->size + sizeof(struct block_header)); } } allocator_release_lock(); } pcre-8.31/sljit/sljitConfigInternal.h0000644000222100022210000003155111754162760014567 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _SLJIT_CONFIG_INTERNAL_H_ #define _SLJIT_CONFIG_INTERNAL_H_ /* SLJIT defines the following macros depending on the target architecture: Feature detection (boolean) macros: SLJIT_32BIT_ARCHITECTURE : 32 bit architecture SLJIT_64BIT_ARCHITECTURE : 64 bit architecture SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_w/sljit_uw array by index SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index SLJIT_LITTLE_ENDIAN : little endian architecture SLJIT_BIG_ENDIAN : big endian architecture SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!) SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information Types and useful macros: sljit_b, sljit_ub : signed and unsigned 8 bit byte sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type sljit_i, sljit_ui : signed and unsigned 32 bit integer type sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t) SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper) */ #if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) #error "An architecture must be selected" #endif /* Sanity check. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 #error "Multiple architectures are selected" #endif /* Auto select option (requires compiler support) */ #if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) #ifndef _WIN32 #if defined(__i386__) || defined(__i386) #define SLJIT_CONFIG_X86_32 1 #elif defined(__x86_64__) #define SLJIT_CONFIG_X86_64 1 #elif defined(__arm__) || defined(__ARM__) #ifdef __thumb2__ #define SLJIT_CONFIG_ARM_THUMB2 1 #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) #define SLJIT_CONFIG_ARM_V7 1 #else #define SLJIT_CONFIG_ARM_V5 1 #endif #elif defined(__ppc64__) || defined(__powerpc64__) #define SLJIT_CONFIG_PPC_64 1 #elif defined(__ppc__) || defined(__powerpc__) #define SLJIT_CONFIG_PPC_32 1 #elif defined(__mips__) #define SLJIT_CONFIG_MIPS_32 1 #else /* Unsupported architecture */ #define SLJIT_CONFIG_UNSUPPORTED 1 #endif #else /* !_WIN32 */ #if defined(_M_X64) || defined(__x86_64__) #define SLJIT_CONFIG_X86_64 1 #elif defined(_ARM_) #define SLJIT_CONFIG_ARM_V5 1 #else #define SLJIT_CONFIG_X86_32 1 #endif #endif /* !WIN32 */ #endif /* SLJIT_CONFIG_AUTO */ #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) #undef SLJIT_EXECUTABLE_ALLOCATOR #endif #if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) /* These libraries are needed for the macros below. */ #include #include #endif /* STD_MACROS_DEFINED */ /* General macros: Note: SLJIT is designed to be independent from them as possible. In release mode (SLJIT_DEBUG is not defined) only the following macros are needed: */ #ifndef SLJIT_MALLOC #define SLJIT_MALLOC(size) malloc(size) #endif #ifndef SLJIT_FREE #define SLJIT_FREE(ptr) free(ptr) #endif #ifndef SLJIT_MEMMOVE #define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) #endif #ifndef SLJIT_ZEROMEM #define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len) #endif #if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) #if defined(__GNUC__) && (__GNUC__ >= 3) #define SLJIT_LIKELY(x) __builtin_expect((x), 1) #define SLJIT_UNLIKELY(x) __builtin_expect((x), 0) #else #define SLJIT_LIKELY(x) (x) #define SLJIT_UNLIKELY(x) (x) #endif #endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */ #ifndef SLJIT_INLINE /* Inline functions. */ #define SLJIT_INLINE __inline #endif #ifndef SLJIT_CONST /* Const variables. */ #define SLJIT_CONST const #endif #ifndef SLJIT_UNUSED_ARG /* Unused arguments. */ #define SLJIT_UNUSED_ARG(arg) (void)arg #endif #if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) /* Static ABI functions. For all-in-one programs. */ #if defined(__GNUC__) /* Disable unused warnings in gcc. */ #define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused)) #else #define SLJIT_API_FUNC_ATTRIBUTE static #endif #else #define SLJIT_API_FUNC_ATTRIBUTE #endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */ #ifndef SLJIT_CACHE_FLUSH #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) /* Not required to implement on archs with unified caches. */ #define SLJIT_CACHE_FLUSH(from, to) #elif defined __APPLE__ /* Supported by all macs since Mac OS 10.5. However, it does not work on non-jailbroken iOS devices, although the compilation is successful. */ #define SLJIT_CACHE_FLUSH(from, to) \ sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) /* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ #define SLJIT_CACHE_FLUSH(from, to) \ ppc_cache_flush((from), (to)) #else /* Calls __ARM_NR_cacheflush on ARM-Linux. */ #define SLJIT_CACHE_FLUSH(from, to) \ __clear_cache((char*)(from), (char*)(to)) #endif #endif /* !SLJIT_CACHE_FLUSH */ /* 8 bit byte type. */ typedef unsigned char sljit_ub; typedef signed char sljit_b; /* 16 bit half-word type. */ typedef unsigned short int sljit_uh; typedef signed short int sljit_h; /* 32 bit integer type. */ typedef unsigned int sljit_ui; typedef signed int sljit_i; /* Machine word type. Can encapsulate a pointer. 32 bit for 32 bit machines. 64 bit for 64 bit machines. */ #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) /* Just to have something. */ #define SLJIT_WORD_SHIFT 0 typedef unsigned long int sljit_uw; typedef long int sljit_w; #elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define SLJIT_32BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 2 typedef unsigned int sljit_uw; typedef int sljit_w; #else #define SLJIT_64BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 3 #ifdef _WIN32 typedef unsigned __int64 sljit_uw; typedef __int64 sljit_w; #else typedef unsigned long int sljit_uw; typedef long int sljit_w; #endif #endif /* Double precision. */ #define SLJIT_FLOAT_SHIFT 3 #ifndef SLJIT_W /* Defining long constants. */ #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) #define SLJIT_W(w) (w##ll) #else #define SLJIT_W(w) (w) #endif #endif /* !SLJIT_W */ #ifndef SLJIT_CALL /* ABI (Application Binary Interface) types. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #if defined(__GNUC__) #define SLJIT_CALL __attribute__ ((fastcall)) #define SLJIT_X86_32_FASTCALL 1 #elif defined(_WIN32) #ifdef __BORLANDC__ #define SLJIT_CALL __msfastcall #else /* __BORLANDC__ */ #define SLJIT_CALL __fastcall #endif /* __BORLANDC__ */ #define SLJIT_X86_32_FASTCALL 1 #else /* defined(_WIN32) */ #define SLJIT_CALL __stdcall #endif #else /* Other architectures. */ #define SLJIT_CALL #endif /* SLJIT_CONFIG_X86_32 */ #endif /* !SLJIT_CALL */ #if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) /* These macros are useful for the application. */ #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define SLJIT_BIG_ENDIAN 1 #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #ifdef __MIPSEL__ #define SLJIT_LITTLE_ENDIAN 1 #else #define SLJIT_BIG_ENDIAN 1 #endif #else #define SLJIT_LITTLE_ENDIAN 1 #endif #endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */ /* Sanity check. */ #if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) #error "Exactly one endianness must be selected" #endif #if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) #error "Exactly one endianness must be selected" #endif #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) /* It seems ppc64 compilers use an indirect addressing for functions. It makes things really complicated. */ #define SLJIT_INDIRECT_CALL 1 #endif #ifndef SLJIT_SSE2 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) /* Turn on SSE2 support on x86. */ #define SLJIT_SSE2 1 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) /* Auto detect SSE2 support using CPUID. On 64 bit x86 cpus, sse2 must be present. */ #define SLJIT_DETECT_SSE2 1 #endif #endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */ #endif /* !SLJIT_SSE2 */ #ifndef SLJIT_UNALIGNED #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define SLJIT_UNALIGNED 1 #endif #endif /* !SLJIT_UNALIGNED */ #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); #define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) #define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) #endif #if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) #include #endif #if (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Feel free to redefine these two macros. */ #ifndef SLJIT_ASSERT #define SLJIT_HALT_PROCESS() \ *((int*)0) = 0 #define SLJIT_ASSERT(x) \ do { \ if (SLJIT_UNLIKELY(!(x))) { \ printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \ SLJIT_HALT_PROCESS(); \ } \ } while (0) #endif /* !SLJIT_ASSERT */ #ifndef SLJIT_ASSERT_STOP #define SLJIT_ASSERT_STOP() \ do { \ printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \ SLJIT_HALT_PROCESS(); \ } while (0) #endif /* !SLJIT_ASSERT_STOP */ #else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ #undef SLJIT_ASSERT #undef SLJIT_ASSERT_STOP #define SLJIT_ASSERT(x) \ do { } while (0) #define SLJIT_ASSERT_STOP() \ do { } while (0) #endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ #ifndef SLJIT_COMPILE_ASSERT /* Should be improved eventually. */ #define SLJIT_COMPILE_ASSERT(x, description) \ SLJIT_ASSERT(x) #endif /* !SLJIT_COMPILE_ASSERT */ #endif pcre-8.31/sljit/sljitNativeMIPS_common.c0000644000222100022210000016447111736614113015151 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "MIPS" SLJIT_CPUINFO; } /* Latest MIPS architecture. */ /* Detect SLJIT_MIPS_32_64 */ /* Length of an instruction word Both for mips-32 and mips-64 */ typedef sljit_ui sljit_ins; #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) /* For position independent code, t9 must contain the function address. */ #define PIC_ADDR_REG TMP_REG2 /* TMP_EREG1 is used mainly for literal encoding on 64 bit. */ #define TMP_EREG1 15 #define TMP_EREG2 24 /* Floating point status register. */ #define FCSR_REG 31 /* Return address register. */ #define RETURN_ADDR_REG 31 /* Flags are keept in volatile registers. */ #define EQUAL_FLAG 7 /* And carry flag as well. */ #define ULESS_FLAG 10 #define UGREATER_FLAG 11 #define LESS_FLAG 12 #define GREATER_FLAG 13 #define OVERFLOW_FLAG 14 #define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) #define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* --------------------------------------------------------------------- */ /* Instrucion forms */ /* --------------------------------------------------------------------- */ #define S(s) (reg_map[s] << 21) #define T(t) (reg_map[t] << 16) #define D(d) (reg_map[d] << 11) /* Absolute registers. */ #define SA(s) ((s) << 21) #define TA(t) ((t) << 16) #define DA(d) ((d) << 11) #define FT(t) ((t) << (16 + 1)) #define FS(s) ((s) << (11 + 1)) #define FD(d) ((d) << (6 + 1)) #define IMM(imm) ((imm) & 0xffff) #define SH_IMM(imm) ((imm & 0x1f) << 6) #define DR(dr) (reg_map[dr]) #define HI(opcode) ((opcode) << 26) #define LO(opcode) (opcode) #define FMT_D (17 << 21) #define ABS_D (HI(17) | FMT_D | LO(5)) #define ADD_D (HI(17) | FMT_D | LO(0)) #define ADDU (HI(0) | LO(33)) #define ADDIU (HI(9)) #define AND (HI(0) | LO(36)) #define ANDI (HI(12)) #define B (HI(4)) #define BAL (HI(1) | (17 << 16)) #define BC1F (HI(17) | (8 << 21)) #define BC1T (HI(17) | (8 << 21) | (1 << 16)) #define BEQ (HI(4)) #define BGEZ (HI(1) | (1 << 16)) #define BGTZ (HI(7)) #define BLEZ (HI(6)) #define BLTZ (HI(1) | (0 << 16)) #define BNE (HI(5)) #define BREAK (HI(0) | LO(13)) #define C_UN_D (HI(17) | FMT_D | LO(49)) #define C_UEQ_D (HI(17) | FMT_D | LO(51)) #define C_ULE_D (HI(17) | FMT_D | LO(55)) #define C_ULT_D (HI(17) | FMT_D | LO(53)) #define DIV (HI(0) | LO(26)) #define DIVU (HI(0) | LO(27)) #define DIV_D (HI(17) | FMT_D | LO(3)) #define J (HI(2)) #define JAL (HI(3)) #define JALR (HI(0) | LO(9)) #define JR (HI(0) | LO(8)) #define LD (HI(55)) #define LDC1 (HI(53)) #define LUI (HI(15)) #define LW (HI(35)) #define NEG_D (HI(17) | FMT_D | LO(7)) #define MFHI (HI(0) | LO(16)) #define MFLO (HI(0) | LO(18)) #define MOV_D (HI(17) | FMT_D | LO(6)) #define CFC1 (HI(17) | (2 << 21)) #define MOVN (HI(0) | LO(11)) #define MOVZ (HI(0) | LO(10)) #define MUL_D (HI(17) | FMT_D | LO(2)) #define MULT (HI(0) | LO(24)) #define MULTU (HI(0) | LO(25)) #define NOP (HI(0) | LO(0)) #define NOR (HI(0) | LO(39)) #define OR (HI(0) | LO(37)) #define ORI (HI(13)) #define SD (HI(63)) #define SDC1 (HI(61)) #define SLT (HI(0) | LO(42)) #define SLTI (HI(10)) #define SLTIU (HI(11)) #define SLTU (HI(0) | LO(43)) #define SLL (HI(0) | LO(0)) #define SLLV (HI(0) | LO(4)) #define SRL (HI(0) | LO(2)) #define SRLV (HI(0) | LO(6)) #define SRA (HI(0) | LO(3)) #define SRAV (HI(0) | LO(7)) #define SUB_D (HI(17) | FMT_D | LO(1)) #define SUBU (HI(0) | LO(35)) #define SW (HI(43)) #define XOR (HI(0) | LO(38)) #define XORI (HI(14)) #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) #define CLZ (HI(28) | LO(32)) #define MUL (HI(28) | LO(2)) #define SEB (HI(31) | (16 << 6) | LO(32)) #define SEH (HI(31) | (24 << 6) | LO(32)) #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define ADDU_W ADDU #define ADDIU_W ADDIU #define SLL_W SLL #define SUBU_W SUBU #else #define ADDU_W DADDU #define ADDIU_W DADDIU #define SLL_W DSLL #define SUBU_W DSUBU #endif #define SIMM_MAX (0x7fff) #define SIMM_MIN (-0x8000) #define UIMM_MAX (0xffff) static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { 0, 2, 5, 6, 3, 8, 16, 17, 18, 19, 20, 29, 4, 25, 9 }; /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ static int push_inst(struct sljit_compiler *compiler, sljit_ins ins, int delay_slot) { sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); *ptr = ins; compiler->size++; compiler->delay_slot = delay_slot; return SLJIT_SUCCESS; } static SLJIT_INLINE sljit_ins invert_branch(int flags) { return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); } static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_w diff; sljit_uw target_addr; sljit_ins *inst; sljit_ins saved_inst; if (jump->flags & SLJIT_REWRITABLE_JUMP) return code_ptr; if (jump->flags & JUMP_ADDR) target_addr = jump->u.target; else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); target_addr = (sljit_uw)(code + jump->u.label->size); } inst = (sljit_ins*)jump->addr; if (jump->flags & IS_COND) inst--; /* B instructions. */ if (jump->flags & IS_MOVABLE) { diff = ((sljit_w)target_addr - (sljit_w)(inst)) >> 2; if (diff <= SIMM_MAX && diff >= SIMM_MIN) { jump->flags |= PATCH_B; if (!(jump->flags & IS_COND)) { inst[0] = inst[-1]; inst[-1] = (jump->flags & IS_JAL) ? BAL : B; jump->addr -= sizeof(sljit_ins); return inst; } saved_inst = inst[0]; inst[0] = inst[-1]; inst[-1] = saved_inst ^ invert_branch(jump->flags); jump->addr -= 2 * sizeof(sljit_ins); return inst; } } diff = ((sljit_w)target_addr - (sljit_w)(inst + 1)) >> 2; if (diff <= SIMM_MAX && diff >= SIMM_MIN) { jump->flags |= PATCH_B; if (!(jump->flags & IS_COND)) { inst[0] = (jump->flags & IS_JAL) ? BAL : B; inst[1] = NOP; return inst + 1; } inst[0] = inst[0] ^ invert_branch(jump->flags); inst[1] = NOP; jump->addr -= sizeof(sljit_ins); return inst + 1; } if (jump->flags & IS_COND) { if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) { jump->flags |= PATCH_J; inst[0] = (inst[0] & 0xffff0000) | 3; inst[1] = NOP; inst[2] = J; inst[3] = NOP; jump->addr += sizeof(sljit_ins); return inst + 3; } return code_ptr; } /* J instuctions. */ if (jump->flags & IS_MOVABLE) { if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) { jump->flags |= PATCH_J; inst[0] = inst[-1]; inst[-1] = (jump->flags & IS_JAL) ? JAL : J; jump->addr -= sizeof(sljit_ins); return inst; } } if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) { jump->flags |= PATCH_J; inst[0] = (jump->flags & IS_JAL) ? JAL : J; inst[1] = NOP; return inst + 1; } return code_ptr; } #ifdef __GNUC__ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr) { SLJIT_CACHE_FLUSH(code, code_ptr); } #endif SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; sljit_ins *code; sljit_ins *code_ptr; sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; sljit_uw addr; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; CHECK_ERROR_PTR(); check_sljit_generate_code(compiler); reverse_buf(compiler); code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; code_ptr = code; word_count = 0; label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { *code_ptr = *buf_ptr++; SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); /* These structures are ordered by their address. */ if (label && label->size == word_count) { /* Just recording the address. */ label->addr = (sljit_uw)code_ptr; label->size = code_ptr - code; label = label->next; } if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) jump->addr = (sljit_uw)(code_ptr - 3); #else jump->addr = (sljit_uw)(code_ptr - 6); #endif code_ptr = optimize_jump(jump, code_ptr, code); jump = jump->next; } if (const_ && const_->addr == word_count) { /* Just recording the address. */ const_->addr = (sljit_uw)code_ptr; const_ = const_->next; } code_ptr ++; word_count ++; } while (buf_ptr < buf_end); buf = buf->next; } while (buf); if (label && label->size == word_count) { label->addr = (sljit_uw)code_ptr; label->size = code_ptr - code; label = label->next; } SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); jump = compiler->jumps; while (jump) { do { addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; buf_ptr = (sljit_ins*)jump->addr; if (jump->flags & PATCH_B) { addr = (sljit_w)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; SLJIT_ASSERT((sljit_w)addr <= SIMM_MAX && (sljit_w)addr >= SIMM_MIN); buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff); break; } if (jump->flags & PATCH_J) { SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)); buf_ptr[0] |= (addr >> 2) & 0x03ffffff; break; } /* Set the fields of immediate loads. */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); #else buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); #endif } while (0); jump = jump->next; } compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = compiler->size * sizeof(sljit_ins); #ifndef __GNUC__ SLJIT_CACHE_FLUSH(code, code_ptr); #else /* GCC workaround for invalid code generation with -O2. */ sljit_cache_flush(code, code_ptr); #endif return code; } /* Creates an index in data_transfer_insts array. */ #define WORD_DATA 0x00 #define BYTE_DATA 0x01 #define HALF_DATA 0x02 #define INT_DATA 0x03 #define SIGNED_DATA 0x04 #define LOAD_DATA 0x08 #define MEM_MASK 0x0f #define WRITE_BACK 0x00010 #define ARG_TEST 0x00020 #define CUMULATIVE_OP 0x00040 #define LOGICAL_OP 0x00080 #define IMM_OP 0x00100 #define SRC2_IMM 0x00200 #define UNUSED_DEST 0x00400 #define REG_DEST 0x00800 #define REG1_SOURCE 0x01000 #define REG2_SOURCE 0x02000 #define SLOW_SRC1 0x04000 #define SLOW_SRC2 0x08000 #define SLOW_DEST 0x10000 /* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */ #define CHECK_FLAGS(list) \ (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #include "sljitNativeMIPS_32.c" #else #include "sljitNativeMIPS_64.c" #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define STACK_STORE SW #define STACK_LOAD LW #else #define STACK_STORE SD #define STACK_LOAD LD #endif static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w); SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { sljit_ins base; CHECK_ERROR(); check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif local_size += (saveds + 1 + 4) * sizeof(sljit_w); local_size = (local_size + 15) & ~0xf; compiler->local_size = local_size; if (local_size <= SIMM_MAX) { /* Frequent case. */ FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_LOCALS_REG) | T(SLJIT_LOCALS_REG) | IMM(-local_size), DR(SLJIT_LOCALS_REG))); base = S(SLJIT_LOCALS_REG); } else { FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_LOCALS_REG) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_LOCALS_REG) | T(TMP_REG1) | D(SLJIT_LOCALS_REG), DR(SLJIT_LOCALS_REG))); base = S(TMP_REG2); local_size = 0; } FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 1) FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 2) FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 3) FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 4) FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 5) FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (args >= 1) FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_SAVED_REG1), DR(SLJIT_SAVED_REG1))); if (args >= 2) FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_SAVED_REG2), DR(SLJIT_SAVED_REG2))); if (args >= 3) FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_SAVED_REG3), DR(SLJIT_SAVED_REG3))); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { CHECK_ERROR_VOID(); check_sljit_set_context(compiler, args, temporaries, saveds, local_size); compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif local_size += (saveds + 1 + 4) * sizeof(sljit_w); compiler->local_size = (local_size + 15) & ~0xf; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { int local_size; sljit_ins base; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); local_size = compiler->local_size; if (local_size <= SIMM_MAX) base = S(SLJIT_LOCALS_REG); else { FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_LOCALS_REG) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1))); base = S(TMP_REG1); local_size = 0; } FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG)); if (compiler->saveds >= 5) FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG2))); if (compiler->saveds >= 4) FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG1))); if (compiler->saveds >= 3) FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG3))); if (compiler->saveds >= 2) FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG2))); if (compiler->saveds >= 1) FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG1))); FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); if (compiler->local_size <= SIMM_MAX) return push_inst(compiler, ADDIU_W | S(SLJIT_LOCALS_REG) | T(SLJIT_LOCALS_REG) | IMM(compiler->local_size), UNMOVABLE_INS); else return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_LOCALS_REG), UNMOVABLE_INS); } #undef STACK_STORE #undef STACK_LOAD /* --------------------------------------------------------------------- */ /* Operators */ /* --------------------------------------------------------------------- */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define ARCH_DEPEND(a, b) a #else #define ARCH_DEPEND(a, b) b #endif static SLJIT_CONST sljit_ins data_transfer_insts[16] = { /* s u w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */), /* s u b */ HI(40) /* sb */, /* s u h */ HI(41) /* sh*/, /* s u i */ HI(43) /* sw */, /* s s w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */), /* s s b */ HI(40) /* sb */, /* s s h */ HI(41) /* sh*/, /* s s i */ HI(43) /* sw */, /* l u w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */), /* l u b */ HI(36) /* lbu */, /* l u h */ HI(37) /* lhu */, /* l u i */ ARCH_DEPEND(HI(35) /* lw */, HI(39) /* lwu */), /* l s w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */), /* l s b */ HI(32) /* lb */, /* l s h */ HI(33) /* lh */, /* l s i */ HI(35) /* lw */, }; /* reg_ar is an absoulute register! */ /* Can perform an operation using at most 1 instruction. */ static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) { SLJIT_ASSERT(arg & SLJIT_MEM); if (!(flags & WRITE_BACK) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { /* Works for both absoulte and relative addresses. */ if (SLJIT_UNLIKELY(flags & ARG_TEST)) return 1; FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & 0xf) | TA(reg_ar) | IMM(argw), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS)); return -1; } return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { if (!(next_arg & SLJIT_MEM)) return 0; /* Simple operation except for updates. */ if (arg & 0xf0) { argw &= 0x3; next_argw &= 0x3; if (argw && argw == next_argw && (arg == next_arg || (arg & 0xf0) == (next_arg & 0xf0))) return 1; return 0; } if (arg == next_arg) { if (((sljit_uw)(next_argw - argw) <= SIMM_MAX && (sljit_uw)(next_argw - argw) >= SIMM_MIN)) return 1; return 0; } return 0; } /* Emit the necessary instructions. See can_cache above. */ static int getput_arg(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { int tmp_ar; int base; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { next_arg = 0; next_argw = 0; } tmp_ar = (flags & LOAD_DATA) ? reg_ar : DR(TMP_REG3); base = arg & 0xf; if (SLJIT_UNLIKELY(arg & 0xf0)) { argw &= 0x3; if ((flags & WRITE_BACK) && reg_ar == DR(base)) { SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); reg_ar = DR(TMP_REG1); } /* Using the cache. */ if (argw == compiler->cache_argw) { if (!(flags & WRITE_BACK)) { if (arg == compiler->cache_arg) return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { if (arg == next_arg && argw == (next_argw & 0x3)) { compiler->cache_arg = arg; compiler->cache_argw = argw; FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar)); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } } else { if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } } } if (SLJIT_UNLIKELY(argw)) { compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); compiler->cache_argw = argw; FAIL_IF(push_inst(compiler, SLL_W | T((arg >> 4) & 0xf) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3))); } if (!(flags & WRITE_BACK)) { if (arg == next_arg && argw == (next_argw & 0x3)) { compiler->cache_arg = arg; compiler->cache_argw = argw; FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); tmp_ar = DR(TMP_REG3); } else FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | DA(tmp_ar), tmp_ar)); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(base), DR(base))); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { /* Update only applies if a base register exists. */ if (reg_ar == DR(base)) { SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); if (argw <= SIMM_MAX && argw >= SIMM_MIN) { FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS)); if (argw) return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)); return SLJIT_SUCCESS; } FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); reg_ar = DR(TMP_REG1); } if (argw <= SIMM_MAX && argw >= SIMM_MIN) { if (argw) FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base))); } else { if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { if (argw != compiler->cache_argw) { FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); compiler->cache_argw = argw; } FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); } else { compiler->cache_arg = SLJIT_MEM; compiler->cache_argw = argw; FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); } } return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { if (argw != compiler->cache_argw) { FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); compiler->cache_argw = argw; } return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { if (argw != compiler->cache_argw) FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); } else { compiler->cache_arg = SLJIT_MEM; FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); } compiler->cache_argw = argw; if (!base) return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) { compiler->cache_arg = arg; FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3))); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar)); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) { if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) return compiler->error; compiler->cache_arg = 0; compiler->cache_argw = 0; return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); } static int emit_op(struct sljit_compiler *compiler, int op, int flags, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ int dst_r = TMP_REG2; int src1_r; sljit_w src2_r = 0; int sugg_src2_r = TMP_REG2; compiler->cache_arg = 0; compiler->cache_argw = 0; if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { dst_r = dst; flags |= REG_DEST; if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } else if (dst == SLJIT_UNUSED) { if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; if (GET_FLAGS(op)) flags |= UNUSED_DEST; } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) flags |= SLOW_DEST; if (flags & IMM_OP) { if ((src2 & SLJIT_IMM) && src2w) { if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN)) || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) { flags |= SRC2_IMM; src2_r = src2w; } } if ((src1 & SLJIT_IMM) && src1w && (flags & CUMULATIVE_OP) && !(flags & SRC2_IMM)) { if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN)) || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) { flags |= SRC2_IMM; src2_r = src1w; /* And swap arguments. */ src1 = src2; src1w = src2w; src2 = SLJIT_IMM; /* src2w = src2_r unneeded. */ } } } /* Source 1. */ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) { src1_r = src1; flags |= REG1_SOURCE; } else if (src1 & SLJIT_IMM) { if (src1w) { FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); src1_r = TMP_REG1; } else src1_r = 0; } else { if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w)) FAIL_IF(compiler->error); else flags |= SLOW_SRC1; src1_r = TMP_REG1; } /* Source 2. */ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { src2_r = src2; flags |= REG2_SOURCE; if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { if (!(flags & SRC2_IMM)) { if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) { FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); src2_r = sugg_src2_r; } else src2_r = 0; } } else { if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w)) FAIL_IF(compiler->error); else flags |= SLOW_SRC2; src2_r = sugg_src2_r; } if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { SLJIT_ASSERT(src2_r == TMP_REG2); if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w)); FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); } else { FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w)); FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw)); } } else if (flags & SLOW_SRC1) FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); else if (flags & SLOW_SRC2) FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw)); FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); if (dst & SLJIT_MEM) { if (!(flags & SLOW_DEST)) { getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw); return compiler->error; } return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); op = GET_OPCODE(op); switch (op) { case SLJIT_BREAKPOINT: return push_inst(compiler, BREAK, UNMOVABLE_INS); case SLJIT_NOP: return push_inst(compiler, NOP, UNMOVABLE_INS); case SLJIT_UMUL: case SLJIT_SMUL: FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); case SLJIT_UDIV: case SLJIT_SDIV: #if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); #endif FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define inp_flags 0 #endif CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); switch (GET_OPCODE(op)) { case SLJIT_MOV: return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UI: return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_SI: return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UB: return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOV_SB: return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOV_UH: return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOV_SH: return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_MOVU: return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UI: return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_SI: return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UB: return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOVU_SB: return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOVU_UH: return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOVU_SH: return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_NEG: return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), inp_flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); case SLJIT_CLZ: return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #undef inp_flags #endif } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define inp_flags 0 #endif CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); switch (GET_OPCODE(op)) { case SLJIT_ADD: case SLJIT_ADDC: return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUB: case SLJIT_SUBC: return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: return emit_op(compiler, op, inp_flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_AND: case SLJIT_OR: case SLJIT_XOR: return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: case SLJIT_LSHR: case SLJIT_ASHR: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) if (src2 & SLJIT_IMM) src2w &= 0x1f; #else if (src2 & SLJIT_IMM) src2w &= 0x3f; #endif return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #undef inp_flags #endif } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); SLJIT_ASSERT(size == 4); return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); } /* --------------------------------------------------------------------- */ /* Floating point operators */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { #if (defined SLJIT_QEMU && SLJIT_QEMU) /* Qemu says fir is 0 by default. */ return 1; #elif defined(__GNUC__) sljit_w fir; asm ("cfc1 %0, $0" : "=r"(fir)); return (fir >> 22) & 0x1; #else #error "FIR check is not implemented for this architecture" #endif } static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) { int hi_reg; SLJIT_ASSERT(arg & SLJIT_MEM); /* Fast loads and stores. */ if (!(arg & 0xf0)) { /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */ if (argw <= SIMM_MAX && argw >= SIMM_MIN) return push_inst(compiler, (load ? LDC1 : SDC1) | S(arg & 0xf) | FT(fpu_reg) | IMM(argw), MOVABLE_INS); } if (arg & 0xf0) { argw &= 0x3; hi_reg = (arg >> 4) & 0xf; if (argw) { FAIL_IF(push_inst(compiler, SLL_W | T(hi_reg) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1))); hi_reg = TMP_REG1; } FAIL_IF(push_inst(compiler, ADDU_W | S(hi_reg) | T(arg & 0xf) | D(TMP_REG1), DR(TMP_REG1))); return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG1) | FT(fpu_reg) | IMM(0), MOVABLE_INS); } /* Use cache. */ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(argw - compiler->cache_argw), MOVABLE_INS); /* Put value to cache. */ compiler->cache_arg = arg; compiler->cache_argw = argw; FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); if (arg & 0xf) FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(arg & 0xf) | D(TMP_REG3), DR(TMP_REG3))); return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(0), MOVABLE_INS); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { int dst_fr; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); compiler->cache_arg = 0; compiler->cache_argw = 0; if (GET_OPCODE(op) == SLJIT_FCMP) { if (dst > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); dst = TMP_FREG1; } if (src > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); src = TMP_FREG2; } /* src and dst are swapped. */ if (op & SLJIT_SET_E) { FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG)); } if (op & SLJIT_SET_S) { /* Mixing the instructions for the two checks. */ FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG)); FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG)); FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG)); FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG)); FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG)); FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG)); } return push_inst(compiler, C_UN_D | FT(src) | FS(dst), FCSR_FCC); } dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; if (src > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw)); src = dst_fr; } switch (op) { case SLJIT_FMOV: if (src != dst_fr && dst_fr != TMP_FREG1) FAIL_IF(push_inst(compiler, MOV_D | FS(src) | FD(dst_fr), MOVABLE_INS)); break; case SLJIT_FNEG: FAIL_IF(push_inst(compiler, NEG_D | FS(src) | FD(dst_fr), MOVABLE_INS)); break; case SLJIT_FABS: FAIL_IF(push_inst(compiler, ABS_D | FS(src) | FD(dst_fr), MOVABLE_INS)); break; } if (dst_fr == TMP_FREG1) FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { int dst_fr; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; if (src2 > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; } if (src1 > SLJIT_FLOAT_REG4) { FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); src1 = TMP_FREG1; } switch (op) { case SLJIT_FADD: FAIL_IF(push_inst(compiler, ADD_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; case SLJIT_FSUB: FAIL_IF(push_inst(compiler, SUB_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; case SLJIT_FMUL: FAIL_IF(push_inst(compiler, MUL_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; case SLJIT_FDIV: FAIL_IF(push_inst(compiler, DIV_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; } if (dst_fr == TMP_FREG1) FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); else if (dst & SLJIT_MEM) return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); else if (src & SLJIT_MEM) FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); else if (src & SLJIT_IMM) FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw)); FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); return push_inst(compiler, NOP, UNMOVABLE_INS); } /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { struct sljit_label *label; CHECK_ERROR_PTR(); check_sljit_emit_label(compiler); if (compiler->last_label && compiler->last_label->size == compiler->size) return compiler->last_label; label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); PTR_FAIL_IF(!label); set_label(label, compiler); compiler->delay_slot = UNMOVABLE_INS; return label; } #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define JUMP_LENGTH 4 #else #define JUMP_LENGTH 7 #endif #define BR_Z(src) \ inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \ flags = IS_BIT26_COND; \ delay_check = src; #define BR_NZ(src) \ inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \ flags = IS_BIT26_COND; \ delay_check = src; #define BR_T() \ inst = BC1T | JUMP_LENGTH; \ flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; #define BR_F() \ inst = BC1F | JUMP_LENGTH; \ flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; sljit_ins inst; int flags = 0; int delay_check = UNMOVABLE_INS; CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; switch (type) { case SLJIT_C_EQUAL: case SLJIT_C_FLOAT_NOT_EQUAL: BR_NZ(EQUAL_FLAG); break; case SLJIT_C_NOT_EQUAL: case SLJIT_C_FLOAT_EQUAL: BR_Z(EQUAL_FLAG); break; case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: BR_Z(ULESS_FLAG); break; case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: BR_NZ(ULESS_FLAG); break; case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: BR_Z(UGREATER_FLAG); break; case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: BR_NZ(UGREATER_FLAG); break; case SLJIT_C_SIG_LESS: BR_Z(LESS_FLAG); break; case SLJIT_C_SIG_GREATER_EQUAL: BR_NZ(LESS_FLAG); break; case SLJIT_C_SIG_GREATER: BR_Z(GREATER_FLAG); break; case SLJIT_C_SIG_LESS_EQUAL: BR_NZ(GREATER_FLAG); break; case SLJIT_C_OVERFLOW: case SLJIT_C_MUL_OVERFLOW: BR_Z(OVERFLOW_FLAG); break; case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_MUL_NOT_OVERFLOW: BR_NZ(OVERFLOW_FLAG); break; case SLJIT_C_FLOAT_NAN: BR_F(); break; case SLJIT_C_FLOAT_NOT_NAN: BR_T(); break; default: /* Not conditional branch. */ inst = 0; break; } jump->flags |= flags; if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check)) jump->flags |= IS_MOVABLE; if (inst) PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS)); PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); if (type <= SLJIT_JUMP) { PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); jump->addr = compiler->size; PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); } else { SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); /* Cannot be optimized out if type is >= CALL0. */ jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0); PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); jump->addr = compiler->size; /* A NOP if type < CALL1. */ PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); } return jump; } #define RESOLVE_IMM1() \ if (src1 & SLJIT_IMM) { \ if (src1w) { \ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \ src1 = TMP_REG1; \ } \ else \ src1 = 0; \ } #define RESOLVE_IMM2() \ if (src2 & SLJIT_IMM) { \ if (src2w) { \ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \ src2 = TMP_REG2; \ } \ else \ src2 = 0; \ } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { struct sljit_jump *jump; int flags; sljit_ins inst; CHECK_ERROR_PTR(); check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; if (src1 & SLJIT_MEM) { if (getput_arg_fast(compiler, flags, DR(TMP_REG1), src1, src1w)) PTR_FAIL_IF(compiler->error); else PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); src1 = TMP_REG1; } if (src2 & SLJIT_MEM) { if (getput_arg_fast(compiler, flags, DR(TMP_REG2), src2, src2w)) PTR_FAIL_IF(compiler->error); else PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0)); src2 = TMP_REG2; } jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; if (type <= SLJIT_C_NOT_EQUAL) { RESOLVE_IMM1(); RESOLVE_IMM2(); jump->flags |= IS_BIT26_COND; if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2))) jump->flags |= IS_MOVABLE; PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS)); } else if (type >= SLJIT_C_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) { inst = NOP; if ((src1 & SLJIT_IMM) && (src1w == 0)) { RESOLVE_IMM2(); switch (type) { case SLJIT_C_SIG_LESS: inst = BLEZ; jump->flags |= IS_BIT26_COND; break; case SLJIT_C_SIG_GREATER_EQUAL: inst = BGTZ; jump->flags |= IS_BIT26_COND; break; case SLJIT_C_SIG_GREATER: inst = BGEZ; jump->flags |= IS_BIT16_COND; break; case SLJIT_C_SIG_LESS_EQUAL: inst = BLTZ; jump->flags |= IS_BIT16_COND; break; } src1 = src2; } else { RESOLVE_IMM1(); switch (type) { case SLJIT_C_SIG_LESS: inst = BGEZ; jump->flags |= IS_BIT16_COND; break; case SLJIT_C_SIG_GREATER_EQUAL: inst = BLTZ; jump->flags |= IS_BIT16_COND; break; case SLJIT_C_SIG_GREATER: inst = BLEZ; jump->flags |= IS_BIT26_COND; break; case SLJIT_C_SIG_LESS_EQUAL: inst = BGTZ; jump->flags |= IS_BIT26_COND; break; } } PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS)); } else { if (type == SLJIT_C_LESS || type == SLJIT_C_GREATER_EQUAL || type == SLJIT_C_SIG_LESS || type == SLJIT_C_SIG_GREATER_EQUAL) { RESOLVE_IMM1(); if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN) PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1))); else { RESOLVE_IMM2(); PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1))); } type = (type == SLJIT_C_LESS || type == SLJIT_C_SIG_LESS) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL; } else { RESOLVE_IMM2(); if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN) PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1))); else { RESOLVE_IMM1(); PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1))); } type = (type == SLJIT_C_GREATER || type == SLJIT_C_SIG_GREATER) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL; } jump->flags |= IS_BIT26_COND; PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS)); } PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); jump->addr = compiler->size; PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); return jump; } #undef RESOLVE_IMM1 #undef RESOLVE_IMM2 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { struct sljit_jump *jump; sljit_ins inst; int if_true; CHECK_ERROR_PTR(); check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; if (src1 > SLJIT_FLOAT_REG4) { PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); src1 = TMP_FREG1; } if (src2 > SLJIT_FLOAT_REG4) { PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; } jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); jump->flags |= IS_BIT16_COND; type &= 0xff; switch (type) { case SLJIT_C_FLOAT_EQUAL: inst = C_UEQ_D; if_true = 1; break; case SLJIT_C_FLOAT_NOT_EQUAL: inst = C_UEQ_D; if_true = 0; break; case SLJIT_C_FLOAT_LESS: inst = C_ULT_D; if_true = 1; break; case SLJIT_C_FLOAT_GREATER_EQUAL: inst = C_ULT_D; if_true = 0; break; case SLJIT_C_FLOAT_GREATER: inst = C_ULE_D; if_true = 0; break; case SLJIT_C_FLOAT_LESS_EQUAL: inst = C_ULE_D; if_true = 1; break; case SLJIT_C_FLOAT_NAN: inst = C_UN_D; if_true = 1; break; case SLJIT_C_FLOAT_NOT_NAN: default: /* Make compilers happy. */ inst = C_UN_D; if_true = 0; break; } PTR_FAIL_IF(push_inst(compiler, inst | FT(src2) | FS(src1), UNMOVABLE_INS)); /* Intentionally the other opcode. */ PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS)); PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); jump->addr = compiler->size; PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); return jump; } #undef JUMP_LENGTH #undef BR_Z #undef BR_NZ #undef BR_T #undef BR_F SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { int src_r = TMP_REG2; struct sljit_jump *jump = NULL; CHECK_ERROR(); check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { if (DR(src) != 4) src_r = src; else FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); } if (type >= SLJIT_CALL0) { SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); if (src & (SLJIT_IMM | SLJIT_MEM)) { if (src & SLJIT_IMM) FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); else { SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); } FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); /* We need an extra instruction in any case. */ return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); } /* Register input. */ if (type >= SLJIT_CALL1) FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS); } if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); jump->u.target = srcw; if (compiler->delay_slot != UNMOVABLE_INS) jump->flags |= IS_MOVABLE; FAIL_IF(emit_const(compiler, TMP_REG2, 0)); } else if (src & SLJIT_MEM) FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS)); if (jump) jump->addr = compiler->size; FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { int sugg_dst_ar, dst_ar; CHECK_ERROR(); check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; sugg_dst_ar = DR((op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2); switch (type) { case SLJIT_C_EQUAL: case SLJIT_C_NOT_EQUAL: FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); dst_ar = sugg_dst_ar; break; case SLJIT_C_LESS: case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_LESS: case SLJIT_C_FLOAT_GREATER_EQUAL: dst_ar = ULESS_FLAG; break; case SLJIT_C_GREATER: case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_GREATER: case SLJIT_C_FLOAT_LESS_EQUAL: dst_ar = UGREATER_FLAG; break; case SLJIT_C_SIG_LESS: case SLJIT_C_SIG_GREATER_EQUAL: dst_ar = LESS_FLAG; break; case SLJIT_C_SIG_GREATER: case SLJIT_C_SIG_LESS_EQUAL: dst_ar = GREATER_FLAG; break; case SLJIT_C_OVERFLOW: case SLJIT_C_NOT_OVERFLOW: dst_ar = OVERFLOW_FLAG; break; case SLJIT_C_MUL_OVERFLOW: case SLJIT_C_MUL_NOT_OVERFLOW: FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); dst_ar = sugg_dst_ar; type ^= 0x1; /* Flip type bit for the XORI below. */ break; case SLJIT_C_FLOAT_EQUAL: case SLJIT_C_FLOAT_NOT_EQUAL: dst_ar = EQUAL_FLAG; break; case SLJIT_C_FLOAT_NAN: case SLJIT_C_FLOAT_NOT_NAN: FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); dst_ar = sugg_dst_ar; break; default: SLJIT_ASSERT_STOP(); dst_ar = sugg_dst_ar; break; } if (type & 0x1) { FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); dst_ar = sugg_dst_ar; } if (GET_OPCODE(op) == SLJIT_OR) { if (DR(TMP_REG2) != dst_ar) FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0); } if (dst & SLJIT_MEM) return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw); if (sugg_dst_ar != dst_ar) return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; int reg; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); ADJUST_LOCAL_OFFSET(dst, dstw); const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); set_const(const_, compiler); reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); return const_; } pcre-8.31/sljit/sljitNativeX86_common.c0000644000222100022210000022371711754162760014773 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "x86" SLJIT_CPUINFO; } /* 32b register indexes: 0 - EAX 1 - ECX 2 - EDX 3 - EBX 4 - none 5 - EBP 6 - ESI 7 - EDI */ /* 64b register indexes: 0 - RAX 1 - RCX 2 - RDX 3 - RBX 4 - none 5 - RBP 6 - RSI 7 - RDI 8 - R8 - From now on REX prefix is required 9 - R9 10 - R10 11 - R11 12 - R12 13 - R13 14 - R14 15 - R15 */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) /* Last register + 1. */ #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1) static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = { 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5 }; #define CHECK_EXTRA_REGS(p, w, do) \ if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \ w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \ do; \ } \ else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \ w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \ do; \ } #else /* SLJIT_CONFIG_X86_32 */ /* Last register + 1. */ #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present Note: avoid to use r12 and r13 for memory addessing therefore r12 is better for SAVED_EREG than SAVED_REG. */ #ifndef _WIN64 /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9 }; /* low-map. reg_map & 0x7. */ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1 }; #else /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 15, 4, 10, 8, 9 }; /* low-map. reg_map & 0x7. */ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 7, 4, 2, 0, 1 }; #endif #define REX_W 0x48 #define REX_R 0x44 #define REX_X 0x42 #define REX_B 0x41 #define REX 0x40 typedef unsigned int sljit_uhw; typedef int sljit_hw; #define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll) #define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll) #define CHECK_EXTRA_REGS(p, w, do) #endif /* SLJIT_CONFIG_X86_32 */ #if (defined SLJIT_SSE2 && SLJIT_SSE2) #define TMP_FREG (SLJIT_FLOAT_REG4 + 1) #endif /* Size flags for emit_x86_instruction: */ #define EX86_BIN_INS 0x0010 #define EX86_SHIFT_INS 0x0020 #define EX86_REX 0x0040 #define EX86_NO_REXW 0x0080 #define EX86_BYTE_ARG 0x0100 #define EX86_HALF_ARG 0x0200 #define EX86_PREF_66 0x0400 #if (defined SLJIT_SSE2 && SLJIT_SSE2) #define EX86_PREF_F2 0x0800 #define EX86_SSE2 0x1000 #endif #define INC_SIZE(s) (*buf++ = (s), compiler->size += (s)) #define INC_CSIZE(s) (*code++ = (s), compiler->size += (s)) #define PUSH_REG(r) (*buf++ = (0x50 + (r))) #define POP_REG(r) (*buf++ = (0x58 + (r))) #define RET() (*buf++ = (0xc3)) #define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0) /* r32, r/m32 */ #define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm)) static sljit_ub get_jump_code(int type) { switch (type) { case SLJIT_C_EQUAL: case SLJIT_C_FLOAT_EQUAL: return 0x84; case SLJIT_C_NOT_EQUAL: case SLJIT_C_FLOAT_NOT_EQUAL: return 0x85; case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: return 0x82; case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: return 0x83; case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: return 0x87; case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: return 0x86; case SLJIT_C_SIG_LESS: return 0x8c; case SLJIT_C_SIG_GREATER_EQUAL: return 0x8d; case SLJIT_C_SIG_GREATER: return 0x8f; case SLJIT_C_SIG_LESS_EQUAL: return 0x8e; case SLJIT_C_OVERFLOW: case SLJIT_C_MUL_OVERFLOW: return 0x80; case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_MUL_NOT_OVERFLOW: return 0x81; case SLJIT_C_FLOAT_NAN: return 0x8a; case SLJIT_C_FLOAT_NOT_NAN: return 0x8b; } return 0; } static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type); #endif static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type) { int short_jump; sljit_uw label_addr; if (jump->flags & JUMP_LABEL) label_addr = (sljit_uw)(code + jump->u.label->size); else label_addr = jump->u.target; short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll) return generate_far_jump_code(jump, code_ptr, type); #endif if (type == SLJIT_JUMP) { if (short_jump) *code_ptr++ = 0xeb; else *code_ptr++ = 0xe9; jump->addr++; } else if (type >= SLJIT_FAST_CALL) { short_jump = 0; *code_ptr++ = 0xe8; jump->addr++; } else if (short_jump) { *code_ptr++ = get_jump_code(type) - 0x10; jump->addr++; } else { *code_ptr++ = 0x0f; *code_ptr++ = get_jump_code(type); jump->addr += 2; } if (short_jump) { jump->flags |= PATCH_MB; code_ptr += sizeof(sljit_b); } else { jump->flags |= PATCH_MW; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) code_ptr += sizeof(sljit_w); #else code_ptr += sizeof(sljit_hw); #endif } return code_ptr; } SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; sljit_ub *code; sljit_ub *code_ptr; sljit_ub *buf_ptr; sljit_ub *buf_end; sljit_ub len; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; CHECK_ERROR_PTR(); check_sljit_generate_code(compiler); reverse_buf(compiler); /* Second code generation pass. */ code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; code_ptr = code; label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; do { buf_ptr = buf->memory; buf_end = buf_ptr + buf->used_size; do { len = *buf_ptr++; if (len > 0) { /* The code is already generated. */ SLJIT_MEMMOVE(code_ptr, buf_ptr, len); code_ptr += len; buf_ptr += len; } else { if (*buf_ptr >= 4) { jump->addr = (sljit_uw)code_ptr; if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4); else code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4); jump = jump->next; } else if (*buf_ptr == 0) { label->addr = (sljit_uw)code_ptr; label->size = code_ptr - code; label = label->next; } else if (*buf_ptr == 1) { const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w); const_ = const_->next; } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */; buf_ptr++; *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w)); code_ptr += sizeof(sljit_w); buf_ptr += sizeof(sljit_w) - 1; #else code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr); buf_ptr += sizeof(sljit_w); #endif } buf_ptr++; } } while (buf_ptr < buf_end); SLJIT_ASSERT(buf_ptr == buf_end); buf = buf->next; } while (buf); SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); jump = compiler->jumps; while (jump) { if (jump->flags & PATCH_MB) { SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127); *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))); } else if (jump->flags & PATCH_MW) { if (jump->flags & JUMP_LABEL) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w))); #else SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll); *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))); #endif } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w))); #else SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll); *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw))); #endif } } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) else if (jump->flags & PATCH_MD) *(sljit_w*)jump->addr = jump->u.label->addr; #endif jump = jump->next; } /* Maybe we waste some space because of short jumps. */ SLJIT_ASSERT(code_ptr <= code + compiler->size); compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = compiler->size; return (void*)code; } /* --------------------------------------------------------------------- */ /* Operators */ /* --------------------------------------------------------------------- */ static int emit_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w); static int emit_non_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w); static int emit_mov(struct sljit_compiler *compiler, int dst, sljit_w dstw, int src, sljit_w srcw); static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler) { sljit_ub *buf; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) buf = (sljit_ub*)ensure_buf(compiler, 1 + 5); FAIL_IF(!buf); INC_SIZE(5); #else buf = (sljit_ub*)ensure_buf(compiler, 1 + 6); FAIL_IF(!buf); INC_SIZE(6); *buf++ = REX_W; #endif *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */ *buf++ = 0x64; *buf++ = 0x24; *buf++ = (sljit_ub)sizeof(sljit_w); *buf++ = 0x9c; /* pushfd / pushfq */ compiler->flags_saved = 1; return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags) { sljit_ub *buf; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) buf = (sljit_ub*)ensure_buf(compiler, 1 + 5); FAIL_IF(!buf); INC_SIZE(5); *buf++ = 0x9d; /* popfd */ #else buf = (sljit_ub*)ensure_buf(compiler, 1 + 6); FAIL_IF(!buf); INC_SIZE(6); *buf++ = 0x9d; /* popfq */ *buf++ = REX_W; #endif *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */ *buf++ = 0x64; *buf++ = 0x24; *buf++ = (sljit_ub)-(int)sizeof(sljit_w); compiler->flags_saved = keep_flags; return SLJIT_SUCCESS; } #ifdef _WIN32 #include static void SLJIT_CALL sljit_grow_stack(sljit_w local_size) { /* Workaround for calling the internal _chkstk() function on Windows. This function touches all 4k pages belongs to the requested stack space, which size is passed in local_size. This is necessary on Windows where the stack can only grow in 4k steps. However, this function just burn CPU cycles if the stack is large enough, but you don't know it in advance. I think this is a bad design even if it has some reasons. */ alloca(local_size); } #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #include "sljitNativeX86_32.c" #else #include "sljitNativeX86_64.c" #endif static int emit_mov(struct sljit_compiler *compiler, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; if (dst == SLJIT_UNUSED) { /* No destination, doesn't need to setup flags. */ if (src & SLJIT_MEM) { code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); FAIL_IF(!code); *code = 0x8b; } return SLJIT_SUCCESS; } if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); FAIL_IF(!code); *code = 0x89; return SLJIT_SUCCESS; } if (src & SLJIT_IMM) { if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); #else if (!compiler->mode32) { if (NOT_HALFWORD(srcw)) return emit_load_imm64(compiler, dst, srcw); } else return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw); #endif } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (!compiler->mode32 && NOT_HALFWORD(srcw)) { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw)); code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw); FAIL_IF(!code); *code = 0x89; return SLJIT_SUCCESS; } #endif code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw); FAIL_IF(!code); *code = 0xc7; return SLJIT_SUCCESS; } if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); FAIL_IF(!code); *code = 0x8b; return SLJIT_SUCCESS; } /* Memory to memory move. Requires two instruction. */ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); FAIL_IF(!code); *code = 0x8b; code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); FAIL_IF(!code); *code = 0x89; return SLJIT_SUCCESS; } #define EMIT_MOV(compiler, dst, dstw, src, srcw) \ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { sljit_ub *buf; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) int size; #endif CHECK_ERROR(); check_sljit_emit_op0(compiler, op); switch (GET_OPCODE(op)) { case SLJIT_BREAKPOINT: buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); *buf = 0xcc; break; case SLJIT_NOP: buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); *buf = 0x90; break; case SLJIT_UMUL: case SLJIT_SMUL: case SLJIT_UDIV: case SLJIT_SDIV: compiler->flags_saved = 0; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #ifdef _WIN64 SLJIT_COMPILE_ASSERT( reg_map[SLJIT_TEMPORARY_REG1] == 0 && reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[TMP_REGISTER] > 7, invalid_register_assignment_for_div_mul); #else SLJIT_COMPILE_ASSERT( reg_map[SLJIT_TEMPORARY_REG1] == 0 && reg_map[SLJIT_TEMPORARY_REG2] < 7 && reg_map[TMP_REGISTER] == 2, invalid_register_assignment_for_div_mul); #endif compiler->mode32 = op & SLJIT_INT_OP; #endif op = GET_OPCODE(op); if (op == SLJIT_UDIV) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0); #else buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); #endif FAIL_IF(!buf); *buf = 0x33; } if (op == SLJIT_SDIV) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); #endif /* CDQ instruction */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); *buf = 0x99; #else if (compiler->mode32) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!buf); INC_SIZE(1); *buf = 0x99; } else { buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); FAIL_IF(!buf); INC_SIZE(2); *buf++ = REX_W; *buf = 0x99; } #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); FAIL_IF(!buf); INC_SIZE(2); *buf++ = 0xf7; *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]); #else #ifdef _WIN64 size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2; #else size = (!compiler->mode32) ? 3 : 2; #endif buf = (sljit_ub*)ensure_buf(compiler, 1 + size); FAIL_IF(!buf); INC_SIZE(size); #ifdef _WIN64 if (!compiler->mode32) *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0); else if (op >= SLJIT_UDIV) *buf++ = REX_B; *buf++ = 0xf7; *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]); #else if (!compiler->mode32) *buf++ = REX_W; *buf++ = 0xf7; *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2]; #endif #endif switch (op) { case SLJIT_UMUL: *buf |= 4 << 3; break; case SLJIT_SMUL: *buf |= 5 << 3; break; case SLJIT_UDIV: *buf |= 6 << 3; break; case SLJIT_SDIV: *buf |= 7 << 3; break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0); #endif break; } return SLJIT_SUCCESS; } #define ENCODE_PREFIX(prefix) \ do { \ code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ FAIL_IF(!code); \ INC_CSIZE(1); \ *code = (prefix); \ } while (0) static int emit_mov_byte(struct sljit_compiler *compiler, int sign, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; int dst_r; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) int work_r; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); #else return emit_load_imm64(compiler, dst, srcw); #endif } code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw); FAIL_IF(!code); *code = 0xc6; return SLJIT_SUCCESS; } dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (reg_map[src] >= 4) { SLJIT_ASSERT(dst_r == TMP_REGISTER); EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); } else dst_r = src; #else dst_r = src; #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) { /* src, dst are registers. */ SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER); if (reg_map[dst] < 4) { if (dst != src) EMIT_MOV(compiler, dst, 0, src, 0); code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); FAIL_IF(!code); *code++ = 0x0f; *code = sign ? 0xbe : 0xb6; } else { if (dst != src) EMIT_MOV(compiler, dst, 0, src, 0); if (sign) { /* shl reg, 24 */ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); FAIL_IF(!code); *code |= 0x4 << 3; code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); FAIL_IF(!code); /* shr/sar reg, 24 */ *code |= 0x7 << 3; } else { /* and dst, 0xff */ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0); FAIL_IF(!code); *(code + 1) |= 0x4 << 3; } } return SLJIT_SUCCESS; } #endif else { /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); FAIL_IF(!code); *code++ = 0x0f; *code = sign ? 0xbe : 0xb6; } if (dst & SLJIT_MEM) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (dst_r == TMP_REGISTER) { /* Find a non-used register, whose reg_map[src] < 4. */ if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) { if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4)) work_r = SLJIT_TEMPORARY_REG3; else work_r = SLJIT_TEMPORARY_REG2; } else { if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) work_r = SLJIT_TEMPORARY_REG1; else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2) work_r = SLJIT_TEMPORARY_REG3; else work_r = SLJIT_TEMPORARY_REG2; } if (work_r == SLJIT_TEMPORARY_REG1) { ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]); } else { code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); FAIL_IF(!code); *code = 0x87; } code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); FAIL_IF(!code); *code = 0x88; if (work_r == SLJIT_TEMPORARY_REG1) { ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]); } else { code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); FAIL_IF(!code); *code = 0x87; } } else { code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); FAIL_IF(!code); *code = 0x88; } #else code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); FAIL_IF(!code); *code = 0x88; #endif } return SLJIT_SUCCESS; } static int emit_mov_half(struct sljit_compiler *compiler, int sign, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; int dst_r; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); #else return emit_load_imm64(compiler, dst, srcw); #endif } code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw); FAIL_IF(!code); *code = 0xc7; return SLJIT_SUCCESS; } dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)) dst_r = src; else { code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); FAIL_IF(!code); *code++ = 0x0f; *code = sign ? 0xbf : 0xb7; } if (dst & SLJIT_MEM) { code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); FAIL_IF(!code); *code = 0x89; } return SLJIT_SUCCESS; } static int emit_unary(struct sljit_compiler *compiler, int un_index, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code++ = 0xf7; *code |= (un_index) << 3; return SLJIT_SUCCESS; } if (dst == src && dstw == srcw) { /* Same input and output */ code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!code); *code++ = 0xf7; *code |= (un_index) << 3; return SLJIT_SUCCESS; } if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src, srcw); code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!code); *code++ = 0xf7; *code |= (un_index) << 3; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code++ = 0xf7; *code |= (un_index) << 3; EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } static int emit_not_with_flags(struct sljit_compiler *compiler, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code++ = 0xf7; *code |= 0x2 << 3; code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code = 0x0b; return SLJIT_SUCCESS; } if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src, srcw); code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!code); *code++ = 0xf7; *code |= 0x2 << 3; code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); FAIL_IF(!code); *code = 0x0b; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code++ = 0xf7; *code |= 0x2 << 3; code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code = 0x0b; EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } static int emit_clz(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; int dst_r; SLJIT_UNUSED_ARG(op); if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { /* Just set the zero flag. */ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code++ = 0xf7; *code |= 0x2 << 3; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0); #else code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0); #endif FAIL_IF(!code); *code |= 0x5 << 3; return SLJIT_SUCCESS; } if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); src = TMP_REGISTER; srcw = 0; } code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw); FAIL_IF(!code); *code++ = 0x0f; *code = 0xbd; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) dst_r = dst; else { /* Find an unused temporary register. */ if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) dst_r = SLJIT_TEMPORARY_REG1; else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4)) dst_r = SLJIT_TEMPORARY_REG2; else dst_r = SLJIT_TEMPORARY_REG3; EMIT_MOV(compiler, dst, dstw, dst_r, 0); } EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); #else dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2; compiler->mode32 = 0; EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); compiler->mode32 = op & SLJIT_INT_OP; #endif code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code++ = 0x0f; *code = 0x45; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); #else code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); #endif FAIL_IF(!code); *(code + 1) |= 0x6 << 3; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (dst & SLJIT_MEM) { code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); FAIL_IF(!code); *code = 0x87; } #else if (dst & SLJIT_MEM) EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0); #endif return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { sljit_ub* code; int update = 0; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) int dst_is_ereg = 0; int src_is_ereg = 0; #else #define src_is_ereg 0 #endif CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1); CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = op & SLJIT_INT_OP; #endif if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { op = GET_OPCODE(op); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); if (op >= SLJIT_MOVU) { update = 1; op -= 7; } if (src & SLJIT_IMM) { switch (op) { case SLJIT_MOV_UB: srcw = (unsigned char)srcw; break; case SLJIT_MOV_SB: srcw = (signed char)srcw; break; case SLJIT_MOV_UH: srcw = (unsigned short)srcw; break; case SLJIT_MOV_SH: srcw = (signed short)srcw; break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) case SLJIT_MOV_UI: srcw = (unsigned int)srcw; break; case SLJIT_MOV_SI: srcw = (signed int)srcw; break; #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (SLJIT_UNLIKELY(dst_is_ereg)) return emit_mov(compiler, dst, dstw, src, srcw); #endif } if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) { code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw); FAIL_IF(!code); *code = 0x8d; src &= SLJIT_MEM | 0xf; srcw = 0; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) { SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG)); dst = TMP_REGISTER; } #endif switch (op) { case SLJIT_MOV: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) case SLJIT_MOV_UI: case SLJIT_MOV_SI: #endif FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); break; case SLJIT_MOV_UB: FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw)); break; case SLJIT_MOV_SB: FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw)); break; case SLJIT_MOV_UH: FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw)); break; case SLJIT_MOV_SH: FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw)); break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) case SLJIT_MOV_UI: FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw)); break; case SLJIT_MOV_SI: FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw)); break; #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REGISTER) return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REGISTER, 0); #endif if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) { code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw); FAIL_IF(!code); *code = 0x8d; } return SLJIT_SUCCESS; } if (SLJIT_UNLIKELY(GET_FLAGS(op))) compiler->flags_saved = 0; switch (GET_OPCODE(op)) { case SLJIT_NOT: if (SLJIT_UNLIKELY(op & SLJIT_SET_E)) return emit_not_with_flags(compiler, dst, dstw, src, srcw); return emit_unary(compiler, 0x2, dst, dstw, src, srcw); case SLJIT_NEG: if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); return emit_unary(compiler, 0x3, dst, dstw, src, srcw); case SLJIT_CLZ: if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); return emit_clz(compiler, op, dst, dstw, src, srcw); } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #undef src_is_ereg #endif } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \ if (IS_HALFWORD(immw) || compiler->mode32) { \ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ FAIL_IF(!code); \ *(code + 1) |= (_op_imm_); \ } \ else { \ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \ FAIL_IF(!code); \ *code = (_op_mr_); \ } #define BINARY_EAX_IMM(_op_eax_imm_, immw) \ FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw)) #else #define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ FAIL_IF(!code); \ *(code + 1) |= (_op_imm_); #define BINARY_EAX_IMM(_op_eax_imm_, immw) \ FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw)) #endif static int emit_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); FAIL_IF(!code); *code = op_rm; } return SLJIT_SUCCESS; } if (dst == src1 && dstw == src1w) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src2w); } else { BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); FAIL_IF(!code); *code = op_rm; } else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) { /* Special exception for sljit_emit_cond_value. */ code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); FAIL_IF(!code); *code = op_mr; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); FAIL_IF(!code); *code = op_mr; } return SLJIT_SUCCESS; } /* Only for cumulative operations. */ if (dst == src2 && dstw == src2w) { if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src1w); } else { BINARY_IMM(op_imm, op_mr, src1w, dst, dstw); } } else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); FAIL_IF(!code); *code = op_rm; } else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); FAIL_IF(!code); *code = op_mr; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); FAIL_IF(!code); *code = op_mr; } return SLJIT_SUCCESS; } /* General version. */ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); FAIL_IF(!code); *code = op_rm; } } else { /* This version requires less memory writing. */ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); FAIL_IF(!code); *code = op_rm; } EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); } return SLJIT_SUCCESS; } static int emit_non_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); FAIL_IF(!code); *code = op_rm; } return SLJIT_SUCCESS; } if (dst == src1 && dstw == src1w) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src2w); } else { BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); FAIL_IF(!code); *code = op_rm; } else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); FAIL_IF(!code); *code = op_mr; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); FAIL_IF(!code); *code = op_mr; } return SLJIT_SUCCESS; } /* General version. */ if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); FAIL_IF(!code); *code = op_rm; } } else { /* This version requires less memory writing. */ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); FAIL_IF(!code); *code = op_rm; } EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); } return SLJIT_SUCCESS; } static int emit_mul(struct sljit_compiler *compiler, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { sljit_ub* code; int dst_r; dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; /* Register destination. */ if (dst_r == src1 && !(src2 & SLJIT_IMM)) { code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); FAIL_IF(!code); *code++ = 0x0f; *code = 0xaf; } else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); FAIL_IF(!code); *code++ = 0x0f; *code = 0xaf; } else if (src1 & SLJIT_IMM) { if (src2 & SLJIT_IMM) { EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w); src2 = dst_r; src2w = 0; } if (src1w <= 127 && src1w >= -128) { code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!code); *code = 0x6b; code = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!code); INC_CSIZE(1); *code = (sljit_b)src1w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!code); *code = 0x69; code = (sljit_ub*)ensure_buf(compiler, 1 + 4); FAIL_IF(!code); INC_CSIZE(4); *(sljit_w*)code = src1w; } #else else if (IS_HALFWORD(src1w)) { code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!code); *code = 0x69; code = (sljit_ub*)ensure_buf(compiler, 1 + 4); FAIL_IF(!code); INC_CSIZE(4); *(sljit_hw*)code = (sljit_hw)src1w; } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); if (dst_r != src2) EMIT_MOV(compiler, dst_r, 0, src2, src2w); code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); FAIL_IF(!code); *code++ = 0x0f; *code = 0xaf; } #endif } else if (src2 & SLJIT_IMM) { /* Note: src1 is NOT immediate. */ if (src2w <= 127 && src2w >= -128) { code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!code); *code = 0x6b; code = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!code); INC_CSIZE(1); *code = (sljit_b)src2w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!code); *code = 0x69; code = (sljit_ub*)ensure_buf(compiler, 1 + 4); FAIL_IF(!code); INC_CSIZE(4); *(sljit_w*)code = src2w; } #else else if (IS_HALFWORD(src2w)) { code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!code); *code = 0x69; code = (sljit_ub*)ensure_buf(compiler, 1 + 4); FAIL_IF(!code); INC_CSIZE(4); *(sljit_hw*)code = (sljit_hw)src2w; } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); if (dst_r != src1) EMIT_MOV(compiler, dst_r, 0, src1, src1w); code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); FAIL_IF(!code); *code++ = 0x0f; *code = 0xaf; } #endif } else { /* Neither argument is immediate. */ if (ADDRESSING_DEPENDS_ON(src2, dst_r)) dst_r = TMP_REGISTER; EMIT_MOV(compiler, dst_r, 0, src1, src1w); code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); FAIL_IF(!code); *code++ = 0x0f; *code = 0xaf; } if (dst_r == TMP_REGISTER) EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } static int emit_lea_binary(struct sljit_compiler *compiler, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { sljit_ub* code; int dst_r, done = 0; /* These cases better be left to handled by normal way. */ if (dst == src1 && dstw == src1w) return SLJIT_ERR_UNSUPPORTED; if (dst == src2 && dstw == src2w) return SLJIT_ERR_UNSUPPORTED; dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) { code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); FAIL_IF(!code); *code = 0x8d; done = 1; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w); #else if (src2 & SLJIT_IMM) { code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); #endif FAIL_IF(!code); *code = 0x8d; done = 1; } } else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w); #else if (src1 & SLJIT_IMM) { code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); #endif FAIL_IF(!code); *code = 0x8d; done = 1; } } if (done) { if (dst_r == TMP_REGISTER) return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } return SLJIT_ERR_UNSUPPORTED; } static int emit_cmp_binary(struct sljit_compiler *compiler, int src1, sljit_w src1w, int src2, sljit_w src2w) { sljit_ub* code; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(0x3d, src2w); return SLJIT_SUCCESS; } if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { if (src2 & SLJIT_IMM) { BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0); } else { code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); FAIL_IF(!code); *code = 0x3b; } return SLJIT_SUCCESS; } if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) { code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); FAIL_IF(!code); *code = 0x39; return SLJIT_SUCCESS; } if (src2 & SLJIT_IMM) { if (src1 & SLJIT_IMM) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); src1 = TMP_REGISTER; src1w = 0; } BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w); } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); FAIL_IF(!code); *code = 0x3b; } return SLJIT_SUCCESS; } static int emit_test_binary(struct sljit_compiler *compiler, int src1, sljit_w src1w, int src2, sljit_w src2w) { sljit_ub* code; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(0xa9, src2w); return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { #endif BINARY_EAX_IMM(0xa9, src1w); return SLJIT_SUCCESS; } if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); FAIL_IF(!code); *code = 0xf7; } else { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0); FAIL_IF(!code); *code = 0x85; } #else code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); FAIL_IF(!code); *code = 0xf7; #endif } else { code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); FAIL_IF(!code); *code = 0x85; } return SLJIT_SUCCESS; } if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src1w) || compiler->mode32) { code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0); FAIL_IF(!code); *code = 0xf7; } else { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0); FAIL_IF(!code); *code = 0x85; } #else code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0); FAIL_IF(!code); *code = 0xf7; #endif } else { code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); FAIL_IF(!code); *code = 0x85; } return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); FAIL_IF(!code); *code = 0xf7; } else { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code = 0x85; } #else code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); FAIL_IF(!code); *code = 0xf7; #endif } else { code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); FAIL_IF(!code); *code = 0x85; } return SLJIT_SUCCESS; } static int emit_shift(struct sljit_compiler *compiler, sljit_ub mode, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { sljit_ub* code; if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { if (dst == src1 && dstw == src1w) { code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); FAIL_IF(!code); *code |= mode; return SLJIT_SUCCESS; } if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); FAIL_IF(!code); *code |= mode; return SLJIT_SUCCESS; } if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); return SLJIT_SUCCESS; } if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src1, src1w); code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); FAIL_IF(!code); *code |= mode; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); FAIL_IF(!code); *code |= mode; EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } if (dst == SLJIT_PREF_SHIFT_REG) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); } else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { if (src1 != dst) EMIT_MOV(compiler, dst, 0, src1, src1w); EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0); EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); FAIL_IF(!code); *code |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); } else { /* This case is really difficult, since ecx itself may used for addressing, and we must ensure to work even in that case. */ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0); #else /* [esp+0] contains the flags. */ EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w), SLJIT_PREF_SHIFT_REG, 0); #endif EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); FAIL_IF(!code); *code |= mode; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0); #else EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w)); #endif EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); } return SLJIT_SUCCESS; } static int emit_shift_with_flags(struct sljit_compiler *compiler, sljit_ub mode, int set_flags, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* The CPU does not set flags if the shift count is 0. */ if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0)) return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); #else if ((src2w & 0x1f) != 0) return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); #endif if (!set_flags) return emit_mov(compiler, dst, dstw, src1, src1w); /* OR dst, src, 0 */ return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d, dst, dstw, src1, src1w, SLJIT_IMM, 0); } if (!set_flags) return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)) FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0)); FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w)); if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); CHECK_EXTRA_REGS(dst, dstw, (void)0); CHECK_EXTRA_REGS(src1, src1w, (void)0); CHECK_EXTRA_REGS(src2, src2w, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = op & SLJIT_INT_OP; #endif if (GET_OPCODE(op) >= SLJIT_MUL) { if (SLJIT_UNLIKELY(GET_FLAGS(op))) compiler->flags_saved = 0; else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); } switch (GET_OPCODE(op)) { case SLJIT_ADD: if (!GET_FLAGS(op)) { if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED) return compiler->error; } else compiler->flags_saved = 0; if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05, dst, dstw, src1, src1w, src2, src2w); case SLJIT_ADDC: if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ FAIL_IF(emit_restore_flags(compiler, 1)); else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) FAIL_IF(emit_save_flags(compiler)); if (SLJIT_UNLIKELY(GET_FLAGS(op))) compiler->flags_saved = 0; return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUB: if (!GET_FLAGS(op)) { if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) return compiler->error; } else compiler->flags_saved = 0; if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); if (dst == SLJIT_UNUSED) return emit_cmp_binary(compiler, src1, src1w, src2, src2w); return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ FAIL_IF(emit_restore_flags(compiler, 1)); else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) FAIL_IF(emit_save_flags(compiler)); if (SLJIT_UNLIKELY(GET_FLAGS(op))) compiler->flags_saved = 0; return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d, dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w); case SLJIT_AND: if (dst == SLJIT_UNUSED) return emit_test_binary(compiler, src1, src1w, src2, src2w); return emit_cum_binary(compiler, 0x23, 0x21, 0x4 << 3, 0x25, dst, dstw, src1, src1w, src2, src2w); case SLJIT_OR: return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d, dst, dstw, src1, src1w, src2, src2w); case SLJIT_XOR: return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op), dst, dstw, src1, src1w, src2, src2w); case SLJIT_LSHR: return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op), dst, dstw, src1, src1w, src2, src2w); case SLJIT_ASHR: return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op), dst, dstw, src1, src1w, src2, src2w); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2 || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2) return -1; #endif return reg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, int size) { sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); SLJIT_ASSERT(size > 0 && size < 16); buf = (sljit_ub*)ensure_buf(compiler, 1 + size); FAIL_IF(!buf); INC_SIZE(size); SLJIT_MEMMOVE(buf, instruction, size); return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ /* Floating point operators */ /* --------------------------------------------------------------------- */ #if (defined SLJIT_SSE2 && SLJIT_SSE2) /* Alignment + 2 * 16 bytes. */ static sljit_i sse2_data[3 + 4 + 4]; static sljit_i *sse2_buffer; static void init_compiler() { sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf); sse2_buffer[0] = 0; sse2_buffer[1] = 0x80000000; sse2_buffer[4] = 0xffffffff; sse2_buffer[5] = 0x7fffffff; } #endif SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { #if (defined SLJIT_SSE2 && SLJIT_SSE2) #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) static int sse2_available = -1; int features; if (sse2_available != -1) return sse2_available; #ifdef __GNUC__ /* AT&T syntax. */ asm ( "pushl %%ebx\n" "movl $0x1, %%eax\n" "cpuid\n" "popl %%ebx\n" "movl %%edx, %0\n" : "=g" (features) : : "%eax", "%ecx", "%edx" ); #elif defined(_MSC_VER) || defined(__BORLANDC__) /* Intel syntax. */ __asm { mov eax, 1 push ebx cpuid pop ebx mov features, edx } #else #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" #endif sse2_available = (features >> 26) & 0x1; return sse2_available; #else return 1; #endif #else return 0; #endif } #if (defined SLJIT_SSE2 && SLJIT_SSE2) static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, int xmm1, int xmm2, sljit_w xmm2w) { sljit_ub *buf; buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w); FAIL_IF(!buf); *buf++ = 0x0f; *buf = opcode; return SLJIT_SUCCESS; } static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, int xmm1, int xmm2, sljit_w xmm2w) { sljit_ub *buf; buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w); FAIL_IF(!buf); *buf++ = 0x0f; *buf = opcode; return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler, int dst, int src, sljit_w srcw) { return emit_sse2(compiler, 0x10, dst, src, srcw); } static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler, int dst, sljit_w dstw, int src) { return emit_sse2(compiler, 0x11, src, dst, dstw); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { int dst_r; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; #endif if (GET_OPCODE(op) == SLJIT_FCMP) { compiler->flags_saved = 0; if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) dst_r = dst; else { dst_r = TMP_FREG; FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw)); } return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw); } if (op == SLJIT_FMOV) { if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) return emit_sse2_load(compiler, dst, src, srcw); if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) return emit_sse2_store(compiler, dst, dstw, src); FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw)); return emit_sse2_store(compiler, dst, dstw, TMP_FREG); } if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) { dst_r = dst; if (dst != src) FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw)); } else { dst_r = TMP_FREG; FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw)); } switch (op) { case SLJIT_FNEG: FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer)); break; case SLJIT_FABS: FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4))); break; } if (dst_r == TMP_FREG) return emit_sse2_store(compiler, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { int dst_r; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; #endif if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) { dst_r = dst; if (dst == src1) ; /* Do nothing here. */ else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) { /* Swap arguments. */ src2 = src1; src2w = src1w; } else if (dst != src2) FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w)); else { dst_r = TMP_FREG; FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w)); } } else { dst_r = TMP_FREG; FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w)); } switch (op) { case SLJIT_FADD: FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w)); break; case SLJIT_FSUB: FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w)); break; case SLJIT_FMUL: FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w)); break; case SLJIT_FDIV: FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w)); break; } if (dst_r == TMP_FREG) return emit_sse2_store(compiler, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } #else SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { CHECK_ERROR(); /* Should cause an assertion fail. */ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); compiler->error = SLJIT_ERR_UNSUPPORTED; return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { CHECK_ERROR(); /* Should cause an assertion fail. */ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); compiler->error = SLJIT_ERR_UNSUPPORTED; return SLJIT_ERR_UNSUPPORTED; } #endif /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { sljit_ub *buf; struct sljit_label *label; CHECK_ERROR_PTR(); check_sljit_emit_label(compiler); /* We should restore the flags before the label, since other taken jumps has their own flags as well. */ if (SLJIT_UNLIKELY(compiler->flags_saved)) PTR_FAIL_IF(emit_restore_flags(compiler, 0)); if (compiler->last_label && compiler->last_label->size == compiler->size) return compiler->last_label; label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); PTR_FAIL_IF(!label); set_label(label, compiler); buf = (sljit_ub*)ensure_buf(compiler, 2); PTR_FAIL_IF(!buf); *buf++ = 0; *buf++ = 0; return label; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { sljit_ub *buf; struct sljit_jump *jump; CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); if (SLJIT_UNLIKELY(compiler->flags_saved)) { if ((type & 0xff) <= SLJIT_JUMP) PTR_FAIL_IF(emit_restore_flags(compiler, 0)); compiler->flags_saved = 0; } jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF_NULL(jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; if (type >= SLJIT_CALL1) PTR_FAIL_IF(call_with_args(compiler, type)); /* Worst case size. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) compiler->size += (type >= SLJIT_JUMP) ? 5 : 6; #else compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3); #endif buf = (sljit_ub*)ensure_buf(compiler, 2); PTR_FAIL_IF_NULL(buf); *buf++ = 0; *buf++ = type + 4; return jump; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { sljit_ub *code; struct sljit_jump *jump; CHECK_ERROR(); check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); CHECK_EXTRA_REGS(src, srcw, (void)0); if (SLJIT_UNLIKELY(compiler->flags_saved)) { if (type <= SLJIT_JUMP) FAIL_IF(emit_restore_flags(compiler, 0)); compiler->flags_saved = 0; } if (type >= SLJIT_CALL1) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (src == SLJIT_TEMPORARY_REG3) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); src = TMP_REGISTER; } if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3) srcw += sizeof(sljit_w); #else if (src == SLJIT_MEM1(SLJIT_LOCALS_REG)) srcw += sizeof(sljit_w) * (type - SLJIT_CALL0); #endif #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) if (src == SLJIT_TEMPORARY_REG3) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); src = TMP_REGISTER; } #endif FAIL_IF(call_with_args(compiler, type)); } if (src == SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF_NULL(jump); set_jump(jump, compiler, JUMP_ADDR); jump->u.target = srcw; /* Worst case size. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) compiler->size += 5; #else compiler->size += 10 + 3; #endif code = (sljit_ub*)ensure_buf(compiler, 2); FAIL_IF_NULL(code); *code++ = 0; *code++ = type + 4; } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) /* REX_W is not necessary (src is not immediate). */ compiler->mode32 = 1; #endif code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!code); *code++ = 0xff; *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3); } return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { sljit_ub *buf; sljit_ub cond_set = 0; int dst_save = dst; sljit_w dstw_save = dstw; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) int reg; #endif CHECK_ERROR(); check_sljit_emit_cond_value(compiler, op, dst, dstw, type); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; ADJUST_LOCAL_OFFSET(dst, dstw); CHECK_EXTRA_REGS(dst, dstw, (void)0); if (SLJIT_UNLIKELY(compiler->flags_saved)) FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS)); switch (type) { case SLJIT_C_EQUAL: case SLJIT_C_FLOAT_EQUAL: cond_set = 0x94; break; case SLJIT_C_NOT_EQUAL: case SLJIT_C_FLOAT_NOT_EQUAL: cond_set = 0x95; break; case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: cond_set = 0x92; break; case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: cond_set = 0x93; break; case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: cond_set = 0x97; break; case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: cond_set = 0x96; break; case SLJIT_C_SIG_LESS: cond_set = 0x9c; break; case SLJIT_C_SIG_GREATER_EQUAL: cond_set = 0x9d; break; case SLJIT_C_SIG_GREATER: cond_set = 0x9f; break; case SLJIT_C_SIG_LESS_EQUAL: cond_set = 0x9e; break; case SLJIT_C_OVERFLOW: case SLJIT_C_MUL_OVERFLOW: cond_set = 0x90; break; case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_MUL_NOT_OVERFLOW: cond_set = 0x91; break; case SLJIT_C_FLOAT_NAN: cond_set = 0x9a; break; case SLJIT_C_FLOAT_NOT_NAN: cond_set = 0x9b; break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); FAIL_IF(!buf); INC_SIZE(4 + 4); /* Set low register to conditional flag. */ *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B; *buf++ = 0x0f; *buf++ = cond_set; *buf++ = 0xC0 | reg_lmap[reg]; *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); *buf++ = 0x0f; *buf++ = 0xb6; *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg]; if (reg == TMP_REGISTER) { if (op == SLJIT_MOV) { compiler->mode32 = 0; EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); } else { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0); } } #else if (op == SLJIT_MOV) { if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) { buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!buf); INC_SIZE(3 + 3); /* Set low byte to conditional flag. */ *buf++ = 0x0f; *buf++ = cond_set; *buf++ = 0xC0 | reg_map[dst]; *buf++ = 0x0f; *buf++ = 0xb6; *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst]; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0); buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!buf); INC_SIZE(3 + 3); /* Set al to conditional flag. */ *buf++ = 0x0f; *buf++ = cond_set; *buf++ = 0xC0; *buf++ = 0x0f; *buf++ = 0xb6; if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS) *buf = 0xC0 | (reg_map[dst] << 3); else { *buf = 0xC0; EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0); } EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0); } } else { if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) { EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0); buf = (sljit_ub*)ensure_buf(compiler, 1 + 3); FAIL_IF(!buf); INC_SIZE(3); *buf++ = 0x0f; *buf++ = cond_set; *buf++ = 0xC0 | reg_map[dst]; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0); buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1); FAIL_IF(!buf); INC_SIZE(3 + 3 + 1); /* Set al to conditional flag. */ *buf++ = 0x0f; *buf++ = cond_set; *buf++ = 0xC0; *buf++ = 0x0f; *buf++ = 0xb6; *buf++ = 0xC0; *buf++ = 0x90 + reg_map[TMP_REGISTER]; } #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0); } #endif return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { CHECK_ERROR(); check_sljit_get_local_base(compiler, dst, dstw, offset); ADJUST_LOCAL_OFFSET(dst, dstw); CHECK_EXTRA_REGS(dst, dstw, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (NOT_HALFWORD(offset)) { FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset)); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED); return compiler->error; #else return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0); #endif } #endif if (offset != 0) return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset); return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0); } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { sljit_ub *buf; struct sljit_const *const_; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) int reg; #endif CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); ADJUST_LOCAL_OFFSET(dst, dstw); CHECK_EXTRA_REGS(dst, dstw, (void)0); const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); set_const(const_, compiler); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; if (emit_load_imm64(compiler, reg, init_value)) return NULL; #else if (dst == SLJIT_UNUSED) dst = TMP_REGISTER; if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value)) return NULL; #endif buf = (sljit_ub*)ensure_buf(compiler, 2); PTR_FAIL_IF(!buf); *buf++ = 0; *buf++ = 1; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (reg == TMP_REGISTER && dst != SLJIT_UNUSED) if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0)) return NULL; #endif return const_; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *(sljit_w*)addr = new_addr - (addr + 4); #else *(sljit_uw*)addr = new_addr; #endif } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { *(sljit_w*)addr = new_constant; } pcre-8.31/sljit/sljitNativeMIPS_32.c0000644000222100022210000003761411676645225014116 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* mips 32-bit arch dependent functions. */ static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm) { if (!(imm & ~0xffff)) return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); if (imm < 0 && imm >= SIMM_MIN) return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; } #define EMIT_LOGICAL(op_imm, op_norm) \ if (flags & SRC2_IMM) { \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ } \ else { \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ } #define EMIT_SHIFT(op_imm, op_norm) \ if (flags & SRC2_IMM) { \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ } \ else { \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \ } static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, int dst, int src1, sljit_w src2) { int overflow_ra = 0; switch (GET_OPCODE(op)) { case SLJIT_ADD: if (flags & SRC2_IMM) { if (op & SLJIT_SET_O) { FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); if (src2 < 0) FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1)); } if (op & SLJIT_SET_E) FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); if (op & SLJIT_SET_C) { if (src2 >= 0) FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); else { FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); } } /* dst may be the same as src1 or src2. */ if (CHECK_FLAGS(SLJIT_SET_E)) FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); if (op & SLJIT_SET_O) { FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); if (src2 < 0) FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG)); } } else { if (op & SLJIT_SET_O) { FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); if (src1 != dst) overflow_ra = DR(src1); else if (src2 != dst) overflow_ra = DR(src2); else { /* Rare ocasion. */ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); overflow_ra = TMP_EREG2; } } if (op & SLJIT_SET_E) FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); /* dst may be the same as src1 or src2. */ if (CHECK_FLAGS(SLJIT_SET_E)) FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); if (op & SLJIT_SET_O) { FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); } } /* a + b >= a | b (otherwise, the carry should be set to 1). */ if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); if (op & SLJIT_SET_O) return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); return SLJIT_SUCCESS; case SLJIT_ADDC: if (flags & SRC2_IMM) { if (op & SLJIT_SET_C) { if (src2 >= 0) FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1)); else { FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1)); FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1)); } } FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); } else { if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); /* dst may be the same as src1 or src2. */ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); } if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1)); FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); if (!(op & SLJIT_SET_C)) return SLJIT_SUCCESS; /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */ FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2)); FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2)); /* Set carry flag. */ return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG); case SLJIT_SUB: if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) { FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); src2 = TMP_REG2; flags &= ~SRC2_IMM; } if (flags & SRC2_IMM) { if (op & SLJIT_SET_O) { FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); if (src2 < 0) FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1)); if (src1 != dst) overflow_ra = DR(src1); else { /* Rare ocasion. */ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); overflow_ra = TMP_EREG2; } } if (op & SLJIT_SET_E) FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); /* dst may be the same as src1 or src2. */ if (CHECK_FLAGS(SLJIT_SET_E)) FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); } else { if (op & SLJIT_SET_O) { FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); if (src1 != dst) overflow_ra = DR(src1); else { /* Rare ocasion. */ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); overflow_ra = TMP_EREG2; } } if (op & SLJIT_SET_E) FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); if (op & (SLJIT_SET_U | SLJIT_SET_C)) FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); if (op & SLJIT_SET_U) FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); if (op & SLJIT_SET_S) { FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); } /* dst may be the same as src1 or src2. */ if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C)) FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); } if (op & SLJIT_SET_O) { FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); } return SLJIT_SUCCESS; case SLJIT_SUBC: if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); src2 = TMP_REG2; flags &= ~SRC2_IMM; } if (flags & SRC2_IMM) { if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1)); /* dst may be the same as src1 or src2. */ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); } else { if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); /* dst may be the same as src1 or src2. */ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); } if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1)); FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); if (op & SLJIT_SET_C) FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG)); return SLJIT_SUCCESS; case SLJIT_MUL: SLJIT_ASSERT(!(flags & SRC2_IMM)); if (!(op & SLJIT_SET_O)) { #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); #else FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); return push_inst(compiler, MFLO | D(dst), DR(dst)); #endif } FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1)); FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2)); return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); case SLJIT_AND: EMIT_LOGICAL(ANDI, AND); return SLJIT_SUCCESS; case SLJIT_OR: EMIT_LOGICAL(ORI, OR); return SLJIT_SUCCESS; case SLJIT_XOR: EMIT_LOGICAL(XORI, XOR); return SLJIT_SUCCESS; case SLJIT_SHL: EMIT_SHIFT(SLL, SLLV); return SLJIT_SUCCESS; case SLJIT_LSHR: EMIT_SHIFT(SRL, SRLV); return SLJIT_SUCCESS; case SLJIT_ASHR: EMIT_SHIFT(SRA, SRAV); return SLJIT_SUCCESS; case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: SLJIT_ASSERT(src1 == TMP_REG1); if (dst != src2) return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); return SLJIT_SUCCESS; case SLJIT_MOV_UB: case SLJIT_MOV_SB: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_SB) { #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); #else FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); #endif } return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); } else if (dst != src2) SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; case SLJIT_MOV_UH: case SLJIT_MOV_SH: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_SH) { #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); #else FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); #endif } return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); } else if (dst != src2) SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; case SLJIT_NOT: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if (op & SLJIT_SET_E) FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); if (CHECK_FLAGS(SLJIT_SET_E)) FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); return SLJIT_SUCCESS; case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) if (op & SLJIT_SET_E) FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); if (CHECK_FLAGS(SLJIT_SET_E)) FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); #else if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); } /* Nearly all instructions are unmovable in the following sequence. */ FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); /* Check zero. */ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); /* Check sign bit. */ FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS)); /* Loop for searching the highest bit. */ FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS)); if (op & SLJIT_SET_E) return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); #endif return SLJIT_SUCCESS; } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) { FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg))); return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg)); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { sljit_ins *inst = (sljit_ins*)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); SLJIT_CACHE_FLUSH(inst, inst + 2); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_ins *inst = (sljit_ins*)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); SLJIT_CACHE_FLUSH(inst, inst + 2); } pcre-8.31/sljit/sljitLir.c0000644000222100022210000014331611762165641012411 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "sljitLir.h" #define CHECK_ERROR() \ do { \ if (SLJIT_UNLIKELY(compiler->error)) \ return compiler->error; \ } while (0) #define CHECK_ERROR_PTR() \ do { \ if (SLJIT_UNLIKELY(compiler->error)) \ return NULL; \ } while (0) #define CHECK_ERROR_VOID() \ do { \ if (SLJIT_UNLIKELY(compiler->error)) \ return; \ } while (0) #define FAIL_IF(expr) \ do { \ if (SLJIT_UNLIKELY(expr)) \ return compiler->error; \ } while (0) #define PTR_FAIL_IF(expr) \ do { \ if (SLJIT_UNLIKELY(expr)) \ return NULL; \ } while (0) #define FAIL_IF_NULL(ptr) \ do { \ if (SLJIT_UNLIKELY(!(ptr))) { \ compiler->error = SLJIT_ERR_ALLOC_FAILED; \ return SLJIT_ERR_ALLOC_FAILED; \ } \ } while (0) #define PTR_FAIL_IF_NULL(ptr) \ do { \ if (SLJIT_UNLIKELY(!(ptr))) { \ compiler->error = SLJIT_ERR_ALLOC_FAILED; \ return NULL; \ } \ } while (0) #define PTR_FAIL_WITH_EXEC_IF(ptr) \ do { \ if (SLJIT_UNLIKELY(!(ptr))) { \ compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \ return NULL; \ } \ } while (0) #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) #define GET_OPCODE(op) \ ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define GET_FLAGS(op) \ ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) #define GET_ALL_FLAGS(op) \ ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define BUF_SIZE 4096 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) #define ABUF_SIZE 2048 #else #define ABUF_SIZE 4096 #endif /* Jump flags. */ #define JUMP_LABEL 0x1 #define JUMP_ADDR 0x2 /* SLJIT_REWRITABLE_JUMP is 0x1000. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define PATCH_MB 0x4 #define PATCH_MW 0x8 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define PATCH_MD 0x10 #endif #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) #define IS_BL 0x4 #define PATCH_B 0x8 #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) #define CPOOL_SIZE 512 #endif #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) #define IS_CONDITIONAL 0x04 #define IS_BL 0x08 /* cannot be encoded as branch */ #define B_TYPE0 0x00 /* conditional + imm8 */ #define B_TYPE1 0x10 /* conditional + imm20 */ #define B_TYPE2 0x20 /* IT + imm24 */ #define B_TYPE3 0x30 /* imm11 */ #define B_TYPE4 0x40 /* imm24 */ #define B_TYPE5 0x50 /* BL + imm24 */ #define BL_TYPE6 0x60 /* 0xf00 cc code for branches */ #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define UNCOND_B 0x04 #define PATCH_B 0x08 #define ABSOLUTE_B 0x10 #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define IS_MOVABLE 0x04 #define IS_JAL 0x08 #define IS_BIT26_COND 0x10 #define IS_BIT16_COND 0x20 #define IS_COND (IS_BIT26_COND | IS_BIT16_COND) #define PATCH_B 0x40 #define PATCH_J 0x80 /* instruction types */ #define UNMOVABLE_INS 0 /* 1 - 31 last destination register */ #define FCSR_FCC 32 /* no destination (i.e: store) */ #define MOVABLE_INS 33 #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1 #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 #ifdef _WIN64 #define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_w)) #else #define FIXED_LOCALS_OFFSET (sizeof(sljit_w)) #endif #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 #define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_w)) #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 #define FIXED_LOCALS_OFFSET (2 * sizeof(sljit_w)) #endif #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 #define FIXED_LOCALS_OFFSET ((7 + 8) * sizeof(sljit_w)) #endif #if (defined SLJIT_HAS_VARIABLE_LOCALS_OFFSET && SLJIT_HAS_VARIABLE_LOCALS_OFFSET) #define ADJUST_LOCAL_OFFSET(p, i) \ if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ (i) += compiler->locals_offset; #elif (defined SLJIT_HAS_FIXED_LOCALS_OFFSET && SLJIT_HAS_FIXED_LOCALS_OFFSET) #define ADJUST_LOCAL_OFFSET(p, i) \ if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ (i) += FIXED_LOCALS_OFFSET; #else #define ADJUST_LOCAL_OFFSET(p, i) #endif #endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */ /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */ #include "sljitUtils.c" #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) #include "sljitExecAllocator.c" #endif #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) && !(defined SLJIT_SSE2 && SLJIT_SSE2) #error SLJIT_SSE2_AUTO cannot be enabled without SLJIT_SSE2 #endif /* --------------------------------------------------------------------- */ /* Public functions */ /* --------------------------------------------------------------------- */ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || ((defined SLJIT_SSE2 && SLJIT_SSE2) && ((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64))) #define SLJIT_NEEDS_COMPILER_INIT 1 static int compiler_initialized = 0; /* A thread safe initialization. */ static void init_compiler(void); #endif SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) { struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler)); if (!compiler) return NULL; SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); SLJIT_COMPILE_ASSERT( sizeof(sljit_b) == 1 && sizeof(sljit_ub) == 1 && sizeof(sljit_h) == 2 && sizeof(sljit_uh) == 2 && sizeof(sljit_i) == 4 && sizeof(sljit_ui) == 4 && ((sizeof(sljit_w) == 4 && sizeof(sljit_uw) == 4) || (sizeof(sljit_w) == 8 && sizeof(sljit_uw) == 8)), invalid_integer_types); /* Only the non-zero members must be set. */ compiler->error = SLJIT_SUCCESS; compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE); compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE); if (!compiler->buf || !compiler->abuf) { if (compiler->buf) SLJIT_FREE(compiler->buf); if (compiler->abuf) SLJIT_FREE(compiler->abuf); SLJIT_FREE(compiler); return NULL; } compiler->buf->next = NULL; compiler->buf->used_size = 0; compiler->abuf->next = NULL; compiler->abuf->used_size = 0; compiler->temporaries = -1; compiler->saveds = -1; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) compiler->args = -1; #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_ub)); if (!compiler->cpool) { SLJIT_FREE(compiler->buf); SLJIT_FREE(compiler->abuf); SLJIT_FREE(compiler); return NULL; } compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE); compiler->cpool_diff = 0xffffffff; #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) compiler->delay_slot = UNMOVABLE_INS; #endif #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) if (!compiler_initialized) { init_compiler(); compiler_initialized = 1; } #endif return compiler; } SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; struct sljit_memory_fragment *curr; buf = compiler->buf; while (buf) { curr = buf; buf = buf->next; SLJIT_FREE(curr); } buf = compiler->abuf; while (buf) { curr = buf; buf = buf->next; SLJIT_FREE(curr); } #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) SLJIT_FREE(compiler->cpool); #endif SLJIT_FREE(compiler); } #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) { /* Remove thumb mode flag. */ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1)); } #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) { /* Resolve indirection. */ code = (void*)(*(sljit_uw*)code); SLJIT_FREE_EXEC(code); } #else SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) { SLJIT_FREE_EXEC(code); } #endif SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) { if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) { jump->flags &= ~JUMP_ADDR; jump->flags |= JUMP_LABEL; jump->u.label = label; } } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) { if (SLJIT_LIKELY(!!jump)) { SLJIT_ASSERT(jump->flags & SLJIT_REWRITABLE_JUMP); jump->flags &= ~JUMP_LABEL; jump->flags |= JUMP_ADDR; jump->u.target = target; } } /* --------------------------------------------------------------------- */ /* Private functions */ /* --------------------------------------------------------------------- */ static void* ensure_buf(struct sljit_compiler *compiler, int size) { sljit_ub *ret; struct sljit_memory_fragment *new_frag; if (compiler->buf->used_size + size <= (int)(BUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) { ret = compiler->buf->memory + compiler->buf->used_size; compiler->buf->used_size += size; return ret; } new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE); PTR_FAIL_IF_NULL(new_frag); new_frag->next = compiler->buf; compiler->buf = new_frag; new_frag->used_size = size; return new_frag->memory; } static void* ensure_abuf(struct sljit_compiler *compiler, int size) { sljit_ub *ret; struct sljit_memory_fragment *new_frag; if (compiler->abuf->used_size + size <= (int)(ABUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) { ret = compiler->abuf->memory + compiler->abuf->used_size; compiler->abuf->used_size += size; return ret; } new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE); PTR_FAIL_IF_NULL(new_frag); new_frag->next = compiler->abuf; compiler->abuf = new_frag; new_frag->used_size = size; return new_frag->memory; } SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size) { CHECK_ERROR_PTR(); #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) if (size <= 0 || size > 128) return NULL; size = (size + 7) & ~7; #else if (size <= 0 || size > 64) return NULL; size = (size + 3) & ~3; #endif return ensure_abuf(compiler, size); } static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf = compiler->buf; struct sljit_memory_fragment *prev = NULL; struct sljit_memory_fragment *tmp; do { tmp = buf->next; buf->next = prev; prev = buf; buf = tmp; } while (buf != NULL); compiler->buf = prev; } static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler) { label->next = NULL; label->size = compiler->size; if (compiler->last_label) compiler->last_label->next = label; else compiler->labels = label; compiler->last_label = label; } static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, int flags) { jump->next = NULL; jump->flags = flags; if (compiler->last_jump) compiler->last_jump->next = jump; else compiler->jumps = jump; compiler->last_jump = jump; } static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler) { const_->next = NULL; const_->addr = compiler->size; if (compiler->last_const) compiler->last_const->next = const_; else compiler->consts = const_; compiler->last_const = const_; } #define ADDRESSING_DEPENDS_ON(exp, reg) \ (((exp) & SLJIT_MEM) && (((exp) & 0xf) == reg || (((exp) >> 4) & 0xf) == reg)) #if (defined SLJIT_DEBUG && SLJIT_DEBUG) #define FUNCTION_CHECK_OP() \ SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ switch (GET_OPCODE(op)) { \ case SLJIT_NOT: \ case SLJIT_CLZ: \ case SLJIT_AND: \ case SLJIT_OR: \ case SLJIT_XOR: \ case SLJIT_SHL: \ case SLJIT_LSHR: \ case SLJIT_ASHR: \ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \ break; \ case SLJIT_NEG: \ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \ break; \ case SLJIT_MUL: \ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \ break; \ case SLJIT_FCMP: \ SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ break; \ case SLJIT_ADD: \ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U))); \ break; \ case SLJIT_SUB: \ break; \ case SLJIT_ADDC: \ case SLJIT_SUBC: \ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \ break; \ default: \ /* Nothing allowed */ \ SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ } #define FUNCTION_CHECK_IS_REG(r) \ ((r) == SLJIT_UNUSED || \ ((r) >= SLJIT_TEMPORARY_REG1 && (r) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \ ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds)) #define FUNCTION_CHECK_SRC(p, i) \ SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ if (FUNCTION_CHECK_IS_REG(p)) \ SLJIT_ASSERT((i) == 0 && (p) != SLJIT_UNUSED); \ else if ((p) == SLJIT_IMM) \ ; \ else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \ else if ((p) & SLJIT_MEM) { \ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \ if ((p) & 0xf0) { \ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \ SLJIT_ASSERT(!((i) & ~0x3)); \ } \ SLJIT_ASSERT(((p) >> 9) == 0); \ } \ else \ SLJIT_ASSERT_STOP(); #define FUNCTION_CHECK_DST(p, i) \ SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ if (FUNCTION_CHECK_IS_REG(p)) \ SLJIT_ASSERT((i) == 0); \ else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \ else if ((p) & SLJIT_MEM) { \ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \ if ((p) & 0xf0) { \ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \ SLJIT_ASSERT(!((i) & ~0x3)); \ } \ SLJIT_ASSERT(((p) >> 9) == 0); \ } \ else \ SLJIT_ASSERT_STOP(); #define FUNCTION_FCHECK(p, i) \ if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG4) \ SLJIT_ASSERT(i == 0); \ else if ((p) & SLJIT_MEM) { \ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \ if ((p) & 0xf0) { \ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \ SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \ } else \ SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \ SLJIT_ASSERT(((p) >> 9) == 0); \ } \ else \ SLJIT_ASSERT_STOP(); #define FUNCTION_CHECK_OP1() \ if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \ SLJIT_ASSERT(!GET_ALL_FLAGS(op)); \ } \ if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \ SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & 0xf) != SLJIT_LOCALS_REG); \ SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & 0xf) != SLJIT_LOCALS_REG); \ if ((src & SLJIT_MEM) && (src & 0xf)) \ SLJIT_ASSERT((dst & 0xf) != (src & 0xf) && ((dst >> 4) & 0xf) != (src & 0xf)); \ } #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) { compiler->verbose = verbose; } static char* reg_names[] = { (char*)"", (char*)"t1", (char*)"t2", (char*)"t3", (char*)"te1", (char*)"te2", (char*)"s1", (char*)"s2", (char*)"s3", (char*)"se1", (char*)"se2", (char*)"lcr" }; static char* freg_names[] = { (char*)"", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", (char*)"float_r4" }; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #ifdef _WIN64 #define SLJIT_PRINT_D "I64" #else #define SLJIT_PRINT_D "l" #endif #else #define SLJIT_PRINT_D "" #endif #define sljit_verbose_param(p, i) \ if ((p) & SLJIT_IMM) \ fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \ else if ((p) & SLJIT_MEM) { \ if ((p) & 0xf) { \ if (i) { \ if (((p) >> 4) & 0xf) \ fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \ else \ fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \ } \ else { \ if (((p) >> 4) & 0xf) \ fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \ else \ fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \ } \ } \ else \ fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ } else \ fprintf(compiler->verbose, "%s", reg_names[p]); #define sljit_verbose_fparam(p, i) \ if ((p) & SLJIT_MEM) { \ if ((p) & 0xf) { \ if (i) { \ if (((p) >> 4) & 0xf) \ fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \ else \ fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \ } \ else { \ if (((p) >> 4) & 0xF) \ fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \ else \ fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \ } \ } \ else \ fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ } else \ fprintf(compiler->verbose, "%s", freg_names[p]); static SLJIT_CONST char* op_names[] = { /* op0 */ (char*)"breakpoint", (char*)"nop", (char*)"umul", (char*)"smul", (char*)"udiv", (char*)"sdiv", /* op1 */ (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh", (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"movu", (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", (char*)"movu.sh", (char*)"movu.ui", (char*)"movu.si", (char*)"not", (char*)"neg", (char*)"clz", /* op2 */ (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", (char*)"shl", (char*)"lshr", (char*)"ashr", /* fop1 */ (char*)"fcmp", (char*)"fmov", (char*)"fneg", (char*)"fabs", /* fop2 */ (char*)"fadd", (char*)"fsub", (char*)"fmul", (char*)"fdiv" }; static char* jump_names[] = { (char*)"c_equal", (char*)"c_not_equal", (char*)"c_less", (char*)"c_greater_equal", (char*)"c_greater", (char*)"c_less_equal", (char*)"c_sig_less", (char*)"c_sig_greater_equal", (char*)"c_sig_greater", (char*)"c_sig_less_equal", (char*)"c_overflow", (char*)"c_not_overflow", (char*)"c_mul_overflow", (char*)"c_mul_not_overflow", (char*)"c_float_equal", (char*)"c_float_not_equal", (char*)"c_float_less", (char*)"c_float_greater_equal", (char*)"c_float_greater", (char*)"c_float_less_equal", (char*)"c_float_nan", (char*)"c_float_not_nan", (char*)"jump", (char*)"fast_call", (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" }; #endif /* --------------------------------------------------------------------- */ /* Arch dependent */ /* --------------------------------------------------------------------- */ static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compiler) { #if (defined SLJIT_DEBUG && SLJIT_DEBUG) struct sljit_jump *jump; #endif /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_ASSERT(compiler->size > 0); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) jump = compiler->jumps; while (jump) { /* All jumps have target. */ SLJIT_ASSERT(jump->flags & (JUMP_LABEL | JUMP_ADDR)); jump = jump->next; } #endif } static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT(args >= 0 && args <= 3); SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); SLJIT_ASSERT(args <= saveds); SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, " enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); #endif } static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; return; } #endif SLJIT_ASSERT(args >= 0 && args <= 3); SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); SLJIT_ASSERT(args <= saveds); SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, " set_context args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); #endif } static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) if (op != SLJIT_UNUSED) { SLJIT_ASSERT(op >= SLJIT_MOV && op <= SLJIT_MOV_SI); FUNCTION_CHECK_SRC(src, srcw); } else SLJIT_ASSERT(src == 0 && srcw == 0); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (op == SLJIT_UNUSED) fprintf(compiler->verbose, " return\n"); else { fprintf(compiler->verbose, " return %s ", op_names[op]); sljit_verbose_param(src, srcw); fprintf(compiler->verbose, "\n"); } } #endif } static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fast_enter "); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_SRC(src, srcw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fast_return "); sljit_verbose_param(src, srcw); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, int op) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_ASSERT((op >= SLJIT_BREAKPOINT && op <= SLJIT_SMUL) || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIV && (op & ~SLJIT_INT_OP) <= SLJIT_SDIV)); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)]); #endif } static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; return; } #endif SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_OP(); FUNCTION_CHECK_SRC(src, srcw); FUNCTION_CHECK_DST(dst, dstw); FUNCTION_CHECK_OP1(); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(src, srcw); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; return; } #endif SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_OP(); FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_param(src2, src2w); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_get_register_index(int reg) { SLJIT_UNUSED_ARG(reg); SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS); } static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, int size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(instruction); SLJIT_UNUSED_ARG(size); SLJIT_ASSERT(instruction); } static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; return; } #endif SLJIT_ASSERT(sljit_is_fpu_available()); SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FCMP && GET_OPCODE(op) <= SLJIT_FABS); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_OP(); FUNCTION_FCHECK(src, srcw); FUNCTION_FCHECK(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s ", op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S"); sljit_verbose_fparam(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src, srcw); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT(sljit_is_fpu_available()); SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FADD && GET_OPCODE(op) <= SLJIT_FDIV); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_OP(); FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); FUNCTION_FCHECK(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s ", op_names[GET_OPCODE(op)]); sljit_verbose_fparam(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src2, src2w); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, "label:\n"); #endif } static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, int type) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; return; } #endif SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP))); SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, " jump%s <%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); #endif } static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT(!(type & ~(0xff | SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP))); SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %scmp%s <%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); sljit_verbose_param(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_param(src2, src2w); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT(sljit_is_fpu_available()); SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP))); SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_NOT_NAN); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fcmp%s <%s> ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); sljit_verbose_fparam(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src2, src2w); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_SRC(src, srcw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " ijump <%s> ", jump_names[type]); sljit_verbose_param(src, srcw); fprintf(compiler->verbose, "\n"); } #endif } static SLJIT_INLINE void check_sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(type); SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP); SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_OR); SLJIT_ASSERT(GET_ALL_FLAGS(op) == 0 || GET_ALL_FLAGS(op) == SLJIT_SET_E || GET_ALL_FLAGS(op) == SLJIT_KEEP_FLAGS); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " cond_set%s%s <%s> ", !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_KEEP_FLAGS) ? "" : "K", op_names[GET_OPCODE(op)]); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", <%s>\n", jump_names[type]); } #endif } static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(offset); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " local_base "); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset); } #endif } static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(init_value); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " const "); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value); } #endif } static SLJIT_INLINE int emit_mov_before_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { /* Return if don't need to do anything. */ if (op == SLJIT_UNUSED) return SLJIT_SUCCESS; #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) if (src == SLJIT_RETURN_REG && op == SLJIT_MOV) return SLJIT_SUCCESS; #else if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI)) return SLJIT_SUCCESS; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw); } /* CPU description section */ #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) #define SLJIT_CPUINFO_PART1 " 32bit (" #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) #define SLJIT_CPUINFO_PART1 " 64bit (" #else #error "Internal error: CPU type info missing" #endif #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) #define SLJIT_CPUINFO_PART2 "little endian + " #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) #define SLJIT_CPUINFO_PART2 "big endian + " #else #error "Internal error: CPU type info missing" #endif #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) #define SLJIT_CPUINFO_PART3 "unaligned)" #else #define SLJIT_CPUINFO_PART3 "aligned)" #endif #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #include "sljitNativeX86_common.c" #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #include "sljitNativeX86_common.c" #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) #include "sljitNativeARM_v5.c" #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) #include "sljitNativeARM_v5.c" #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) #include "sljitNativeARM_Thumb2.c" #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #include "sljitNativePPC_common.c" #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #include "sljitNativePPC_common.c" #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #include "sljitNativeMIPS_common.c" #endif #if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { /* Default compare for most architectures. */ int flags, tmp_src, condition; sljit_w tmp_srcw; CHECK_ERROR_PTR(); check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); condition = type & 0xff; if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { /* Immediate is prefered as second argument by most architectures. */ switch (condition) { case SLJIT_C_LESS: condition = SLJIT_C_GREATER; break; case SLJIT_C_GREATER_EQUAL: condition = SLJIT_C_LESS_EQUAL; break; case SLJIT_C_GREATER: condition = SLJIT_C_LESS; break; case SLJIT_C_LESS_EQUAL: condition = SLJIT_C_GREATER_EQUAL; break; case SLJIT_C_SIG_LESS: condition = SLJIT_C_SIG_GREATER; break; case SLJIT_C_SIG_GREATER_EQUAL: condition = SLJIT_C_SIG_LESS_EQUAL; break; case SLJIT_C_SIG_GREATER: condition = SLJIT_C_SIG_LESS; break; case SLJIT_C_SIG_LESS_EQUAL: condition = SLJIT_C_SIG_GREATER_EQUAL; break; } type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)); tmp_src = src1; src1 = src2; src2 = tmp_src; tmp_srcw = src1w; src1w = src2w; src2w = tmp_srcw; } if (condition <= SLJIT_C_NOT_ZERO) flags = SLJIT_SET_E; else if (condition <= SLJIT_C_LESS_EQUAL) flags = SLJIT_SET_U; else flags = SLJIT_SET_S; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP), SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { int flags, condition; check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); condition = type & 0xff; if (condition <= SLJIT_C_FLOAT_NOT_EQUAL) flags = SLJIT_SET_E; else flags = SLJIT_SET_S; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif sljit_emit_fop1(compiler, SLJIT_FCMP | flags, src1, src1w, src2, src2w); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); } #endif #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { CHECK_ERROR(); check_sljit_get_local_base(compiler, dst, dstw, offset); ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif if (offset != 0) return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset); return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_LOCALS_REG, 0); } #endif #else /* SLJIT_CONFIG_UNSUPPORTED */ /* Empty function bodies for those machines, which are not (yet) supported. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "unsupported"; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) { SLJIT_ASSERT_STOP(); return NULL; } SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) { SLJIT_UNUSED_ARG(compiler); SLJIT_ASSERT_STOP(); } SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(size); SLJIT_ASSERT_STOP(); return NULL; } #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(verbose); SLJIT_ASSERT_STOP(); } #endif SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { SLJIT_UNUSED_ARG(compiler); SLJIT_ASSERT_STOP(); return NULL; } SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) { SLJIT_UNUSED_ARG(code); SLJIT_ASSERT_STOP(); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { SLJIT_ASSERT_STOP(); return reg; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, int size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(instruction); SLJIT_UNUSED_ARG(size); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { SLJIT_ASSERT_STOP(); return 0; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int src1, sljit_w src1w, int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { SLJIT_UNUSED_ARG(compiler); SLJIT_ASSERT_STOP(); return NULL; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); SLJIT_ASSERT_STOP(); return NULL; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT_STOP(); return NULL; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, int src1, sljit_w src1w, int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(src1); SLJIT_UNUSED_ARG(src1w); SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT_STOP(); return NULL; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) { SLJIT_UNUSED_ARG(jump); SLJIT_UNUSED_ARG(label); SLJIT_ASSERT_STOP(); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) { SLJIT_UNUSED_ARG(jump); SLJIT_UNUSED_ARG(target); SLJIT_ASSERT_STOP(); } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(type); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(offset); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w initval) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); SLJIT_UNUSED_ARG(initval); SLJIT_ASSERT_STOP(); return NULL; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { SLJIT_UNUSED_ARG(addr); SLJIT_UNUSED_ARG(new_addr); SLJIT_ASSERT_STOP(); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { SLJIT_UNUSED_ARG(addr); SLJIT_UNUSED_ARG(new_constant); SLJIT_ASSERT_STOP(); } #endif pcre-8.31/sljit/sljitLir.h0000644000222100022210000010665111736614113012411 00000000000000/* * Stack-less Just-In-Time compiler * * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _SLJIT_LIR_H_ #define _SLJIT_LIR_H_ /* ------------------------------------------------------------------------ Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC) ------------------------------------------------------------------------ Short description Advantages: - The execution can be continued from any LIR instruction In other words, jump into and out of the code is safe - Both target of (conditional) jump and call instructions and constants can be dynamically modified during runtime - although it is not suggested to do it frequently - very effective to cache an important value once - A fixed stack space can be allocated for local variables - The compiler is thread-safe - The compiler is highly configurable through preprocessor macros. You can disable unneeded features (multithreading in single threaded applications), and you can use your own system functions (including memory allocators). See sljitConfig.h Disadvantages: - Limited number of registers (only 6+4 integer registers, max 3+2 temporary, max 3+2 saved and 4 floating point registers) In practice: - This approach is very effective for interpreters - One of the saved registers typically points to a stack interface - It can jump to any exception handler anytime (even for another function. It is safe for SLJIT.) - Fast paths can be modified during runtime reflecting the changes of the fastest execution path of the dynamic language - SLJIT supports complex memory addressing modes - mainly position independent code - Optimizations (perhaps later) - Only for basic blocks (when no labels inserted between LIR instructions) For valgrind users: - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code" */ #if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG) #include "sljitConfig.h" #endif /* The following header file defines useful macros for fine tuning sljit based code generators. They are listed in the begining of sljitConfigInternal.h */ #include "sljitConfigInternal.h" /* --------------------------------------------------------------------- */ /* Error codes */ /* --------------------------------------------------------------------- */ /* Indicates no error. */ #define SLJIT_SUCCESS 0 /* After the call of sljit_generate_code(), the error code of the compiler is set to this value to avoid future sljit calls (in debug mode at least). The complier should be freed after sljit_generate_code(). */ #define SLJIT_ERR_COMPILED 1 /* Cannot allocate non executable memory. */ #define SLJIT_ERR_ALLOC_FAILED 2 /* Cannot allocate executable memory. Only for sljit_generate_code() */ #define SLJIT_ERR_EX_ALLOC_FAILED 3 /* return value for SLJIT_CONFIG_UNSUPPORTED empty architecture. */ #define SLJIT_ERR_UNSUPPORTED 4 /* --------------------------------------------------------------------- */ /* Registers */ /* --------------------------------------------------------------------- */ #define SLJIT_UNUSED 0 /* Temporary (scratch) registers may not preserve their values across function calls. */ #define SLJIT_TEMPORARY_REG1 1 #define SLJIT_TEMPORARY_REG2 2 #define SLJIT_TEMPORARY_REG3 3 /* Note: Extra Registers cannot be used for memory addressing. */ /* Note: on x86-32, these registers are emulated (using stack loads & stores). */ #define SLJIT_TEMPORARY_EREG1 4 #define SLJIT_TEMPORARY_EREG2 5 /* Saved registers whose preserve their values across function calls. */ #define SLJIT_SAVED_REG1 6 #define SLJIT_SAVED_REG2 7 #define SLJIT_SAVED_REG3 8 /* Note: Extra Registers cannot be used for memory addressing. */ /* Note: on x86-32, these registers are emulated (using stack loads & stores). */ #define SLJIT_SAVED_EREG1 9 #define SLJIT_SAVED_EREG2 10 /* Read-only register (cannot be the destination of an operation). Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since several ABIs has certain limitations about the stack layout. However sljit_get_local_base() can be used to obtain the offset of a value. */ #define SLJIT_LOCALS_REG 11 /* Number of registers. */ #define SLJIT_NO_TMP_REGISTERS 5 #define SLJIT_NO_GEN_REGISTERS 5 #define SLJIT_NO_REGISTERS 11 /* Return with machine word. */ #define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1 /* x86 prefers specific registers for special purposes. In case of shift by register it supports only SLJIT_TEMPORARY_REG3 for shift argument (which is the src2 argument of sljit_emit_op2). If another register is used, sljit must exchange data between registers which cause a minor slowdown. Other architectures has no such limitation. */ #define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3 /* --------------------------------------------------------------------- */ /* Floating point registers */ /* --------------------------------------------------------------------- */ /* Note: SLJIT_UNUSED as destination is not valid for floating point operations, since they cannot be used for setting flags. */ /* Floating point operations are performed on double precision values. */ #define SLJIT_FLOAT_REG1 1 #define SLJIT_FLOAT_REG2 2 #define SLJIT_FLOAT_REG3 3 #define SLJIT_FLOAT_REG4 4 /* --------------------------------------------------------------------- */ /* Main structures and functions */ /* --------------------------------------------------------------------- */ struct sljit_memory_fragment { struct sljit_memory_fragment *next; sljit_uw used_size; sljit_ub memory[1]; }; struct sljit_label { struct sljit_label *next; sljit_uw addr; /* The maximum size difference. */ sljit_uw size; }; struct sljit_jump { struct sljit_jump *next; sljit_uw addr; sljit_w flags; union { sljit_uw target; struct sljit_label* label; } u; }; struct sljit_const { struct sljit_const *next; sljit_uw addr; }; struct sljit_compiler { int error; struct sljit_label *labels; struct sljit_jump *jumps; struct sljit_const *consts; struct sljit_label *last_label; struct sljit_jump *last_jump; struct sljit_const *last_const; struct sljit_memory_fragment *buf; struct sljit_memory_fragment *abuf; /* Used local registers. */ int temporaries; /* Used saved registers. */ int saveds; /* Local stack size. */ int local_size; /* Code size. */ sljit_uw size; /* For statistical purposes. */ sljit_uw executable_size; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) int args; int locals_offset; int temporaries_start; int saveds_start; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) int mode32; #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) int flags_saved; #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) /* Constant pool handling. */ sljit_uw *cpool; sljit_ub *cpool_unique; sljit_uw cpool_diff; sljit_uw cpool_fill; /* Other members. */ /* Contains pointer, "ldr pc, [...]" pairs. */ sljit_uw patches; #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Temporary fields. */ sljit_uw shift_imm; int cache_arg; sljit_w cache_argw; #endif #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) int cache_arg; sljit_w cache_argw; #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) sljit_w imm; int cache_arg; sljit_w cache_argw; #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) int delay_slot; int cache_arg; sljit_w cache_argw; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) FILE* verbose; #endif #if (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Local size passed to the functions. */ int logical_local_size; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) int skip_checks; #endif }; /* --------------------------------------------------------------------- */ /* Main functions */ /* --------------------------------------------------------------------- */ /* Creates an sljit compiler. Returns NULL if failed. */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void); /* Free everything except the codes. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); static SLJIT_INLINE int sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } /* Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler, and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_w) aligned. Excellent for allocating small blocks during the compiling, and no need to worry about freeing them. The size is enough to contain at most 16 pointers. If the size is outside of the range, the function will return with NULL, but this return value does not indicate that there is no more memory (does not set the compiler to out-of-memory status). */ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); #endif SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler); SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code); /* After the code generation we can retrieve the allocated executable memory size, although this area may not be fully filled with instructions depending on some optimizations. This function is useful only for statistical purposes. Before a successful code generation, this function returns with 0. */ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } /* Instruction generation. Returns with error code. */ /* The executable code is basically a function call from the viewpoint of the C language. The function calls must obey to the ABI (Application Binary Interface) of the platform, which specify the purpose of machine registers and stack handling among other things. The sljit_emit_enter function emits the necessary instructions for setting up a new context for the executable code and moves function arguments to the saved registers. The number of arguments are specified in the "args" parameter and the first argument goes to SLJIT_SAVED_REG1, the second goes to SLJIT_SAVED_REG2 and so on. The number of temporary and saved registers are passed in "temporaries" and "saveds" arguments respectively. Since the saved registers contains the arguments, "args" must be less or equal than "saveds". The sljit_emit_enter is also capable of allocating a stack space for local variables. The "local_size" argument contains the size in bytes of this local area and its staring address is stored in SLJIT_LOCALS_REG. However the SLJIT_LOCALS_REG is not necessary the machine stack pointer. The memory bytes between SLJIT_LOCALS_REG (inclusive) and SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely until the function returns. The stack space is uninitialized. Note: every call of sljit_emit_enter and sljit_set_context overwrites the previous context. */ #define SLJIT_MAX_LOCAL_SIZE 65536 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size); /* The machine code has a context (which contains the local stack space size, number of used registers, etc.) which initialized by sljit_emit_enter. Several functions (like sljit_emit_return) requres this context to be able to generate the appropriate code. However, some code fragments (like inline cache) may have no normal entry point so their context is unknown for the compiler. Using the function below we can specify thir context. Note: every call of sljit_emit_enter and sljit_set_context overwrites the previous context. */ /* Note: multiple calls of this function overwrites the previous call. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size); /* Return from machine code. The op argument can be SLJIT_UNUSED which means the function does not return with anything or any opcode between SLJIT_MOV and SLJIT_MOV_SI (see sljit_emit_op1). As for src and srcw they must be 0 if op is SLJIT_UNUSED, otherwise see below the description about source and destination arguments. */ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw); /* Really fast calling method for utility functions inside sljit (see SLJIT_FAST_CALL). All registers and even the stack frame is passed to the callee. The return address is preserved in dst/dstw by sljit_emit_fast_enter, and sljit_emit_fast_return can use this as a return value later. */ /* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine instructions are needed. Excellent for small uility functions, where saving registers and setting up a new stack frame would cost too much performance. However, it is still possible to return to the address of the caller (or anywhere else). */ /* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */ /* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested, since many architectures do clever branch prediction on call / return instruction pairs. */ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw); SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw); /* Source and destination values for arithmetical instructions imm - a simple immediate value (cannot be used as a destination) reg - any of the registers (immediate argument must be 0) [imm] - absolute immediate memory address [reg+imm] - indirect memory address [reg+(reg<addr; } static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; } static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; } /* Only the address is required to rewrite the code. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr); SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant); /* --------------------------------------------------------------------- */ /* Miscellaneous utility functions */ /* --------------------------------------------------------------------- */ #define SLJIT_MAJOR_VERSION 0 #define SLJIT_MINOR_VERSION 88 /* Get the human readable name of the platfrom. Can be useful for debugging on platforms like ARM, where ARM and Thumb2 functions can be mixed. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); /* Portble helper function to get an offset of a member. */ #define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10) #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) /* This global lock is useful to compile common functions. */ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void); SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void); #endif #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) /* The sljit_stack is a utiliy feature of sljit, which allocates a writable memory region between base (inclusive) and limit (exclusive). Both base and limit is a pointer, and base is always <= than limit. This feature uses the "address space reserve" feature of modern operating systems. Basically we don't need to allocate a huge memory block in one step for the worst case, we can start with a smaller chunk and extend it later. Since the address space is reserved, the data never copied to other regions, thus it is safe to store pointers here. */ /* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more). Note: stack growing should not happen in small steps: 4k, 16k or even bigger growth is better. Note: this structure may not be supported by all operating systems. Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK is not defined. */ struct sljit_stack { /* User data, anything can be stored here. Starting with the same value as base. */ sljit_uw top; /* These members are read only. */ sljit_uw base; sljit_uw limit; sljit_uw max_limit; }; /* Returns NULL if unsuccessful. Note: limit and max_limit contains the size for stack allocation Note: the top field is initialized to base. */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit); SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack); /* Can be used to increase (allocate) or decrease (free) the memory area. Returns with a non-zero value if unsuccessful. If new_limit is greater than max_limit, it will fail. It is very easy to implement a stack data structure, since the growth ratio can be added to the current limit, and sljit_stack_resize will do all the necessary checks. The fields of the stack are not changed if sljit_stack_resize fails. */ SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit); #endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */ #if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) /* Get the entry address of a given function. */ #define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)func_name) #else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ /* All JIT related code should be placed in the same context (library, binary, etc.). */ #define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)*(void**)func_name) /* For powerpc64, the function pointers point to a context descriptor. */ struct sljit_function_context { sljit_w addr; sljit_w r2; sljit_w r11; }; /* Fill the context arguments using the addr and the function. If func_ptr is NULL, it will not be set to the address of context If addr is NULL, the function address also comes from the func pointer. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func); #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ #endif /* _SLJIT_LIR_H_ */ pcre-8.31/ucp.h0000644000222100022210000000704111723162171010246 00000000000000/************************************************* * Unicode Property Table handler * *************************************************/ #ifndef _UCP_H #define _UCP_H /* This file contains definitions of the property values that are returned by the UCD access macros. New values that are added for new releases of Unicode should always be at the end of each enum, for backwards compatibility. */ /* These are the general character categories. */ enum { ucp_C, /* Other */ ucp_L, /* Letter */ ucp_M, /* Mark */ ucp_N, /* Number */ ucp_P, /* Punctuation */ ucp_S, /* Symbol */ ucp_Z /* Separator */ }; /* These are the particular character types. */ enum { ucp_Cc, /* Control */ ucp_Cf, /* Format */ ucp_Cn, /* Unassigned */ ucp_Co, /* Private use */ ucp_Cs, /* Surrogate */ ucp_Ll, /* Lower case letter */ ucp_Lm, /* Modifier letter */ ucp_Lo, /* Other letter */ ucp_Lt, /* Title case letter */ ucp_Lu, /* Upper case letter */ ucp_Mc, /* Spacing mark */ ucp_Me, /* Enclosing mark */ ucp_Mn, /* Non-spacing mark */ ucp_Nd, /* Decimal number */ ucp_Nl, /* Letter number */ ucp_No, /* Other number */ ucp_Pc, /* Connector punctuation */ ucp_Pd, /* Dash punctuation */ ucp_Pe, /* Close punctuation */ ucp_Pf, /* Final punctuation */ ucp_Pi, /* Initial punctuation */ ucp_Po, /* Other punctuation */ ucp_Ps, /* Open punctuation */ ucp_Sc, /* Currency symbol */ ucp_Sk, /* Modifier symbol */ ucp_Sm, /* Mathematical symbol */ ucp_So, /* Other symbol */ ucp_Zl, /* Line separator */ ucp_Zp, /* Paragraph separator */ ucp_Zs /* Space separator */ }; /* These are the script identifications. */ enum { ucp_Arabic, ucp_Armenian, ucp_Bengali, ucp_Bopomofo, ucp_Braille, ucp_Buginese, ucp_Buhid, ucp_Canadian_Aboriginal, ucp_Cherokee, ucp_Common, ucp_Coptic, ucp_Cypriot, ucp_Cyrillic, ucp_Deseret, ucp_Devanagari, ucp_Ethiopic, ucp_Georgian, ucp_Glagolitic, ucp_Gothic, ucp_Greek, ucp_Gujarati, ucp_Gurmukhi, ucp_Han, ucp_Hangul, ucp_Hanunoo, ucp_Hebrew, ucp_Hiragana, ucp_Inherited, ucp_Kannada, ucp_Katakana, ucp_Kharoshthi, ucp_Khmer, ucp_Lao, ucp_Latin, ucp_Limbu, ucp_Linear_B, ucp_Malayalam, ucp_Mongolian, ucp_Myanmar, ucp_New_Tai_Lue, ucp_Ogham, ucp_Old_Italic, ucp_Old_Persian, ucp_Oriya, ucp_Osmanya, ucp_Runic, ucp_Shavian, ucp_Sinhala, ucp_Syloti_Nagri, ucp_Syriac, ucp_Tagalog, ucp_Tagbanwa, ucp_Tai_Le, ucp_Tamil, ucp_Telugu, ucp_Thaana, ucp_Thai, ucp_Tibetan, ucp_Tifinagh, ucp_Ugaritic, ucp_Yi, /* New for Unicode 5.0: */ ucp_Balinese, ucp_Cuneiform, ucp_Nko, ucp_Phags_Pa, ucp_Phoenician, /* New for Unicode 5.1: */ ucp_Carian, ucp_Cham, ucp_Kayah_Li, ucp_Lepcha, ucp_Lycian, ucp_Lydian, ucp_Ol_Chiki, ucp_Rejang, ucp_Saurashtra, ucp_Sundanese, ucp_Vai, /* New for Unicode 5.2: */ ucp_Avestan, ucp_Bamum, ucp_Egyptian_Hieroglyphs, ucp_Imperial_Aramaic, ucp_Inscriptional_Pahlavi, ucp_Inscriptional_Parthian, ucp_Javanese, ucp_Kaithi, ucp_Lisu, ucp_Meetei_Mayek, ucp_Old_South_Arabian, ucp_Old_Turkic, ucp_Samaritan, ucp_Tai_Tham, ucp_Tai_Viet, /* New for Unicode 6.0.0: */ ucp_Batak, ucp_Brahmi, ucp_Mandaic, /* New for Unicode 6.1.0: */ ucp_Chakma, ucp_Meroitic_Cursive, ucp_Meroitic_Hieroglyphs, ucp_Miao, ucp_Sharada, ucp_Sora_Sompeng, ucp_Takri }; #endif /* End of ucp.h */ pcre-8.31/perltest.pl0000755000222100022210000001406111706560434011515 00000000000000#! /usr/bin/env perl # Program for testing regular expressions with perl to check that PCRE handles # them the same. This version supports /8 for UTF-8 testing. However, it needs # to have "use utf8" at the start for running the UTF-8 tests, but *not* for # the other tests. The only way I've found for doing this is to cat this line # in explicitly in the RunPerlTest script. I've also used this method to supply # "require Encode" for the UTF-8 tests, so that the main test will still run # where Encode is not installed. # use locale; # With this included, \x0b matches \s! # Function for turning a string into a string of printing chars. #require Encode; sub pchars { my($t) = ""; if ($utf8) { @p = unpack('U*', $_[0]); foreach $c (@p) { if ($c >= 32 && $c < 127) { $t .= chr $c; } else { $t .= sprintf("\\x{%02x}", $c); } } } else { foreach $c (split(//, $_[0])) { if (ord $c >= 32 && ord $c < 127) { $t .= $c; } else { $t .= sprintf("\\x%02x", ord $c); } } } $t; } # Read lines from named file or stdin and write to named file or stdout; lines # consist of a regular expression, in delimiters and optionally followed by # options, followed by a set of test data, terminated by an empty line. # Sort out the input and output files if (@ARGV > 0) { open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; $infile = "INFILE"; } else { $infile = "STDIN"; } if (@ARGV > 1) { open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; $outfile = "OUTFILE"; } else { $outfile = "STDOUT"; } printf($outfile "Perl $] Regular Expressions\n\n"); # Main loop NEXT_RE: for (;;) { printf " re> " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; next if ($_ eq ""); $pattern = $_; while ($pattern !~ /^\s*(.).*\1/s) { printf " > " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; $pattern .= $_; } chomp($pattern); $pattern =~ s/\s+$//; # The private /+ modifier means "print $' afterwards". $showrest = ($pattern =~ s/\+(?=[a-zA-Z]*$)//); # A doubled version is used by pcretest to print remainders after captures $pattern =~ s/\+(?=[a-zA-Z]*$)//; # Remove /8 from a UTF-8 pattern. $utf8 = $pattern =~ s/8(?=[a-zA-Z]*$)//; # Remove /J from a pattern with duplicate names. $pattern =~ s/J(?=[a-zA-Z]*$)//; # Remove /K from a pattern (asks pcretest to check MARK data) */ $pattern =~ s/K(?=[a-zA-Z]*$)//; # Remove /W from a pattern (asks pcretest to set PCRE_UCP) $pattern =~ s/W(?=[a-zA-Z]*$)//; # Remove /S or /SS from a pattern (asks pcretest to study or not to study) $pattern =~ s/S(?=[a-zA-Z]*$)//g; # Remove /Y from a pattern (asks pcretest to disable PCRE optimization) $pattern =~ s/Y(?=[a-zA-Z]*$)//; # Check that the pattern is valid eval "\$_ =~ ${pattern}"; if ($@) { printf $outfile "Error: $@"; next NEXT_RE; } # If the /g modifier is present, we want to put a loop round the matching; # otherwise just a single "if". $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; # If the pattern is actually the null string, Perl uses the most recently # executed (and successfully compiled) regex is used instead. This is a # nasty trap for the unwary! The PCRE test suite does contain null strings # in places - if they are allowed through here all sorts of weird and # unexpected effects happen. To avoid this, we replace such patterns with # a non-null pattern that has the same effect. $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); # Read data lines and test them for (;;) { printf "data> " if $infile eq "STDIN"; last NEXT_RE if ! ($_ = <$infile>); chomp; printf $outfile "$_\n" if $infile ne "STDIN"; s/\s+$//; # Remove trailing space s/^\s+//; # Remove leading space s/\\Y//g; # Remove \Y (pcretest flag to set PCRE_NO_START_OPTIMIZE) last if ($_ eq ""); $x = eval "\"$_\""; # To get escapes processed # Empty array for holding results, ensure $REGERROR and $REGMARK are # unset, then do the matching. @subs = (); $pushes = "push \@subs,\$&;" . "push \@subs,\$1;" . "push \@subs,\$2;" . "push \@subs,\$3;" . "push \@subs,\$4;" . "push \@subs,\$5;" . "push \@subs,\$6;" . "push \@subs,\$7;" . "push \@subs,\$8;" . "push \@subs,\$9;" . "push \@subs,\$10;" . "push \@subs,\$11;" . "push \@subs,\$12;" . "push \@subs,\$13;" . "push \@subs,\$14;" . "push \@subs,\$15;" . "push \@subs,\$16;" . "push \@subs,\$'; }"; undef $REGERROR; undef $REGMARK; eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; if ($@) { printf $outfile "Error: $@\n"; next NEXT_RE; } elsif (scalar(@subs) == 0) { printf $outfile "No match"; if (defined $REGERROR && $REGERROR != 1) { printf $outfile (", mark = %s", &pchars($REGERROR)); } printf $outfile "\n"; } else { while (scalar(@subs) != 0) { printf $outfile (" 0: %s\n", &pchars($subs[0])); printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; $last_printed = 0; for ($i = 1; $i <= 16; $i++) { if (defined $subs[$i]) { while ($last_printed++ < $i-1) { printf $outfile ("%2d: \n", $last_printed); } printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); $last_printed = $i; } } splice(@subs, 0, 18); } # It seems that $REGMARK is not marked as UTF-8 even when use utf8 is # set and the input pattern was a UTF-8 string. We can, however, force # it to be so marked. if (defined $REGMARK && $REGMARK != 1) { $xx = $REGMARK; $xx = Encode::decode_utf8($xx) if $utf8; printf $outfile ("MK: %s\n", &pchars($xx)); } } } } # printf $outfile "\n"; # End pcre-8.31/README0000644000222100022210000011772411770363601010203 00000000000000README file for PCRE (Perl-compatible regular expression library) ----------------------------------------------------------------- The latest release of PCRE is always available in three alternative formats from: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.bz2 ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip There is a mailing list for discussion about the development of PCRE at pcre-dev@exim.org Please read the NEWS file if you are upgrading from a previous release. The contents of this README file are: The PCRE APIs Documentation for PCRE Contributions by users of PCRE Building PCRE on non-Unix-like systems Building PCRE without using autotools Building PCRE using autotools Retrieving configuration information Shared libraries Cross-compiling using autotools Using HP's ANSI C++ compiler (aCC) Using PCRE from MySQL Making new tarballs Testing PCRE Character tables File manifest The PCRE APIs ------------- PCRE is written in C, and it has its own API. There are two sets of functions, one for the 8-bit library, which processes strings of bytes, and one for the 16-bit library, which processes strings of 16-bit values. The distribution also includes a set of C++ wrapper functions (see the pcrecpp man page for details), courtesy of Google Inc., which can be used to call the 8-bit PCRE library from C++. In addition, there is a set of C wrapper functions (again, just for the 8-bit library) that are based on the POSIX regular expression API (see the pcreposix man page). These end up in the library called libpcreposix. Note that this just provides a POSIX calling interface to PCRE; the regular expressions themselves still follow Perl syntax and semantics. The POSIX API is restricted, and does not give full access to all of PCRE's facilities. The header file for the POSIX-style functions is called pcreposix.h. The official POSIX name is regex.h, but I did not want to risk possible problems with existing files of that name by distributing it that way. To use PCRE with an existing program that uses the POSIX API, pcreposix.h will have to be renamed or pointed at by a link. If you are using the POSIX interface to PCRE and there is already a POSIX regex library installed on your system, as well as worrying about the regex.h header file (as mentioned above), you must also take care when linking programs to ensure that they link with PCRE's libpcreposix library. Otherwise they may pick up the POSIX functions of the same name from the other library. One way of avoiding this confusion is to compile PCRE with the addition of -Dregcomp=PCREregcomp (and similarly for the other POSIX functions) to the compiler flags (CFLAGS if you are using "configure" -- see below). This has the effect of renaming the functions so that the names no longer clash. Of course, you have to do the same thing for your applications, or write them using the new names. Documentation for PCRE ---------------------- If you install PCRE in the normal way on a Unix-like system, you will end up with a set of 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: 1. There are files called doc/pcre.txt, doc/pcregrep.txt, and doc/pcretest.txt in the source distribution. The first of these is a concatenation of the text forms of all the section 3 man pages except those that summarize individual functions. The other two are the text forms of the section 1 man pages for the pcregrep and pcretest commands. These text forms are provided for ease of scanning with text editors or similar tools. They are installed in /share/doc/pcre, where is the installation prefix (defaulting to /usr/local). 2. A set of files containing all the documentation in HTML form, hyperlinked in various ways, and rooted in a file called index.html, is distributed in doc/html and installed in /share/doc/pcre/html. Users of PCRE have contributed files containing the documentation for various releases in CHM format. These can be found in the Contrib directory of the FTP site (see next section). Contributions by users of PCRE ------------------------------ You can find contributions from PCRE users in the directory ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib There is a README file giving brief descriptions of what they are. Some are complete in themselves; others are pointers to URLs containing relevant files. Some of this material is likely to be well out-of-date. Several of the earlier contributions provided support for compiling PCRE on various flavours of Windows (I myself do not use Windows). Nowadays there is more Windows support in the standard distribution, so these contibutions have been archived. Building PCRE on non-Unix-like systems -------------------------------------- For a non-Unix-like system, please read the comments in the file NON-AUTOTOOLS-BUILD, though if your system supports the use of "configure" and "make" you may be able to build PCRE using autotools in the same way as for many Unix-like systems. PCRE can also be configured using the GUI facility provided by CMake's cmake-gui command. This creates Makefiles, solution files, etc. The file NON-AUTOTOOLS-BUILD has information about CMake. PCRE has been compiled on many different operating systems. It should be straightforward to build PCRE on any system that has a Standard C compiler and library, because it uses only Standard C functions. Building PCRE without using autotools ------------------------------------- The use of autotools (in particular, libtool) is problematic in some environments, even some that are Unix or Unix-like. See the NON-AUTOTOOLS-BUILD file for ways of building PCRE without using autotools. Building PCRE using autotools ----------------------------- If you are using HP's ANSI C++ compiler (aCC), please see the special note in the section entitled "Using HP's ANSI C++ compiler (aCC)" below. The following instructions assume the use of the widely used "configure; make; make install" (autotools) process. To build PCRE on system that supports autotools, first run the "configure" command from the PCRE distribution directory, with your current directory set to the directory where you want the files to be created. This command is a standard GNU "autoconf" configuration script, for which generic instructions are supplied in the file INSTALL. Most commonly, people build PCRE within its own distribution directory, and in this case, on many systems, just running "./configure" is sufficient. However, the usual methods of changing standard defaults are available. For example: CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local This command specifies that the C compiler should be run with the flags '-O2 -Wall' instead of the default, and that "make install" should install PCRE under /opt/local instead of the default /usr/local. If you want to build in a different directory, just run "configure" with that directory as current. For example, suppose you have unpacked the PCRE source into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx: cd /build/pcre/pcre-xxx /source/pcre/pcre-xxx/configure PCRE is written in C and is normally compiled as a C library. However, it is possible to build it as a C++ library, though the provided building apparatus does not have any features to support this. There are some optional features that can be included or omitted from the PCRE library. They are also documented in the pcrebuild man page. . By default, both shared and static libraries are built. You can change this by adding one of these options to the "configure" command: --disable-shared --disable-static (See also "Shared libraries on Unix-like systems" below.) . By default, only the 8-bit library is built. If you add --enable-pcre16 to the "configure" command, the 16-bit library is also built. If you want only the 16-bit library, use "./configure --enable-pcre16 --disable-pcre8". . If you are building the 8-bit library and want to suppress the building of the C++ wrapper library, you can add --disable-cpp to the "configure" command. Otherwise, when "configure" is run without --disable-pcre8, it will try to find a C++ compiler and C++ header files, and if it succeeds, it will try to build the C++ wrapper. . If you want to include support for just-in-time compiling, which can give large performance improvements on certain platforms, add --enable-jit to the "configure" command. This support is available only for certain hardware architectures. If you try to enable it on an unsupported architecture, there will be a compile time error. . When JIT support is enabled, pcregrep automatically makes use of it, unless you add --disable-pcregrep-jit to the "configure" command. . If you want to make use of the support for UTF-8 Unicode character strings in the 8-bit library, or UTF-16 Unicode character strings in the 16-bit library, you must add --enable-utf to the "configure" command. Without it, the code for handling UTF-8 and UTF-16 is not included in the relevant library. Even when --enable-utf is included, the use of a UTF encoding still has to be enabled by an option at run time. When PCRE is compiled with this option, its input can only either be ASCII or UTF-8/16, even when running on EBCDIC platforms. It is not possible to use both --enable-utf and --enable-ebcdic at the same time. . There are no separate options for enabling UTF-8 and UTF-16 independently because that would allow ridiculous settings such as requesting UTF-16 support while building only the 8-bit library. However, the option --enable-utf8 is retained for backwards compatibility with earlier releases that did not support 16-bit character strings. It is synonymous with --enable-utf. It is not possible to configure one library with UTF support and the other without in the same configuration. . If, in addition to support for UTF-8/16 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 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 or the sequence CRLF or any of the preceding, or any of the Unicode newline sequences 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 --enable-newline-is-cr or --enable-newline-is-lf or --enable-newline-is-crlf or --enable-newline-is-anycrlf or --enable-newline-is-any to the "configure" command, respectively. If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of the standard tests will fail, because the lines in the test files end with LF. Even if the files are edited to change the line endings, there are likely to be some failures. With --enable-newline-is-anycrlf or --enable-newline-is-any, many tests should succeed, but there may be some failures. . By default, the sequence \R in a pattern matches any Unicode line ending sequence. This is independent of the option specifying what PCRE considers to be the end of a line (see above). However, the caller of PCRE can restrict \R to match only CR, LF, or CRLF. You can make this the default by adding --enable-bsr-anycrlf to the "configure" command (bsr = "backslash R"). . When called via the POSIX interface, PCRE uses malloc() to get additional storage for processing capturing parentheses if there are more than 10 of them in a pattern. You can increase this threshold by setting, for example, --with-posix-malloc-threshold=20 on the "configure" command. . PCRE has a counter that can be set to limit the amount of resources it uses. If the limit is exceeded during a match, the match fails. The default is ten million. You can change the default by setting, for example, --with-match-limit=500000 on the "configure" command. This is just the default; individual calls to pcre_exec() can supply their own value. There is more 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. In the 8-bit library, PCRE then uses three bytes instead of two for offsets to different parts of the compiled pattern. In the 16-bit library, --with-link-size=3 is the same as --with-link-size=4, which (in both libraries) uses four-byte offsets. Increasing the internal link size reduces performance. . You can build PCRE so that its internal match() function that is called from pcre_exec() does not call itself recursively. Instead, it uses memory blocks obtained from the heap via the special functions pcre_stack_malloc() and pcre_stack_free() to save data that would otherwise be saved on the stack. To build PCRE like this, use --disable-stack-for-recursion on the "configure" command. PCRE runs more slowly in this mode, but it may be necessary in environments with limited stack sizes. This applies only to the normal execution of the pcre_exec() function; if JIT support is being successfully used, it is not relevant. Equally, it does not apply to pcre_dfa_exec(), which does not use deeply nested recursion. There is a discussion about stack sizes in the pcrestack man page. . For speed, PCRE uses four tables for manipulating and identifying characters whose code point values are less than 256. By default, it uses a set of tables for ASCII encoding that is part of the distribution. If you specify --enable-rebuild-chartables a program called dftables is compiled and run in the default C locale when you obey "make". It builds a source file called pcre_chartables.c. If you do not specify this option, pcre_chartables.c is created as a copy of pcre_chartables.c.dist. See "Character tables" below for further information. . It is possible to compile PCRE for use on systems that use EBCDIC as their character code (as opposed to ASCII) by specifying --enable-ebcdic This automatically implies --enable-rebuild-chartables (see above). However, when PCRE is built this way, it always operates in EBCDIC. It cannot support both EBCDIC and UTF-8/16. . The pcregrep program currently supports only 8-bit data files, and so requires the 8-bit PCRE library. It is possible to compile pcregrep to use libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by specifying one or both of --enable-pcregrep-libz --enable-pcregrep-libbz2 Of course, the relevant libraries must be installed on your system. . The default size of internal buffer used by pcregrep can be set by, for example: --with-pcregrep-bufsize=50K The default value is 20K. . It is possible to compile pcretest so that it links with the libreadline or libedit libraries, by specifying, respectively, --enable-pcretest-libreadline or --enable-pcretest-libedit If this is done, when pcretest's input is from a terminal, it reads it using the readline() function. This provides line-editing and history facilities. Note that libreadline is GPL-licenced, so if you distribute a binary of pcretest linked in this way, there may be licensing issues. These can be avoided by linking with libedit (which has a BSD licence) instead. Enabling libreadline causes the -lreadline option to be added to the pcretest build. In many operating environments with a sytem-installed readline library this is sufficient. However, in some environments (e.g. if an unmodified distribution version of readline is in use), it may be necessary to specify something like LIBS="-lncurses" as well. This is because, to quote the readline INSTALL, "Readline uses the termcap functions, but does not link with the termcap or curses library itself, allowing applications which link with readline the to choose an appropriate library." If you get error messages about missing functions tgetstr, tgetent, tputs, tgetflag, or tgoto, this is the problem, and linking with the ncurses library should fix it. The "configure" script builds the following files for the basic C library: . Makefile the makefile that builds the library . config.h build-time configuration options for the library . pcre.h the public PCRE header file . pcre-config script that shows the building settings such as CFLAGS that were set for "configure" . libpcre.pc ) data for the pkg-config command . libpcre16.pc ) . libpcreposix.pc ) . libtool script that builds shared and/or static libraries Versions of config.h and pcre.h are distributed in the PCRE tarballs under the names config.h.generic and pcre.h.generic. These are provided for those who have to built PCRE without using "configure" or CMake. If you use "configure" or CMake, the .generic versions are not used. When building the 8-bit library, if a C++ compiler is found, the following files are also built: . libpcrecpp.pc data for the pkg-config command . pcrecpparg.h header file for calling PCRE via the C++ wrapper . pcre_stringpiece.h header for the C++ "stringpiece" functions The "configure" script also creates config.status, which is an executable script that can be run to recreate the configuration, and config.log, which contains compiler output from tests that "configure" runs. Once "configure" has run, you can run "make". This builds either or both of the libraries libpcre and libpcre16, and a test program called pcretest. If you enabled JIT support with --enable-jit, a test program called pcre_jit_test is built as well. If the 8-bit library is built, libpcreposix and the pcregrep command are also built, and if a C++ compiler was found on your system, and you did not disable it with --disable-cpp, "make" builds the C++ wrapper library, which is called libpcrecpp, as well as some test programs called pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest. The command "make check" runs all the appropriate tests. Details of the PCRE tests are given below in a separate section of this document. You can use "make install" to install PCRE into live directories on your system. The following are installed (file names are all relative to the that is set when "configure" is run): Commands (bin): pcretest pcregrep (if 8-bit support is enabled) pcre-config Libraries (lib): libpcre16 (if 16-bit support is enabled) libpcre (if 8-bit support is enabled) libpcreposix (if 8-bit support is enabled) libpcrecpp (if 8-bit and C++ support is enabled) Configuration information (lib/pkgconfig): libpcre16.pc libpcre.pc libpcreposix.pc libpcrecpp.pc (if C++ support is enabled) Header files (include): pcre.h pcreposix.h pcre_scanner.h ) pcre_stringpiece.h ) if C++ support is enabled pcrecpp.h ) pcrecpparg.h ) Man pages (share/man/man{1,3}): pcregrep.1 pcretest.1 pcre-config.1 pcre.3 pcre*.3 (lots more pages, all starting "pcre") HTML documentation (share/doc/pcre/html): index.html *.html (lots more pages, hyperlinked from index.html) Text file documentation (share/doc/pcre): AUTHORS COPYING ChangeLog LICENCE NEWS README pcre.txt (a concatenation of the man(3) pages) pcretest.txt the pcretest man page pcregrep.txt the pcregrep man page pcre-config.txt the pcre-config man page If you want to remove PCRE from your system, you can run "make uninstall". This removes all the files that "make install" installed. However, it does not remove any directories, because these are often shared with other programs. Retrieving configuration information ------------------------------------ Running "make install" installs the command pcre-config, which can be used to recall information about the PCRE configuration and installation. For example: pcre-config --version prints the version number, and pcre-config --libs outputs information about where the library is installed. This command can be included in makefiles for programs that use PCRE, saving the programmer from having to remember too many details. The pkg-config command is another system for saving and retrieving information about installed libraries. Instead of separate commands for each library, a single command is used. For example: pkg-config --cflags pcre The data is held in *.pc files that are installed in a directory called /lib/pkgconfig. Shared libraries ---------------- The default distribution builds PCRE as shared libraries and static libraries, as long as the operating system supports shared libraries. Shared library support relies on the "libtool" script which is built as part of the "configure" process. The libtool script is used to compile and link both shared and static libraries. They are placed in a subdirectory called .libs when they are newly built. The programs pcretest and pcregrep are built to use these uninstalled libraries (by means of wrapper scripts in the case of shared libraries). When you use "make install" to install shared libraries, pcregrep and pcretest are automatically re-built to use the newly installed shared libraries before being installed themselves. However, the versions left in the build directory still use the uninstalled libraries. To build PCRE using static libraries only you must use --disable-shared when configuring it. For example: ./configure --prefix=/usr/gnu --disable-shared Then run "make" in the usual way. Similarly, you can use --disable-static to build only shared libraries. Cross-compiling using autotools ------------------------------- You can specify CC and CFLAGS in the normal way to the "configure" command, in order to cross-compile PCRE for some other host. However, you should NOT specify --enable-rebuild-chartables, because if you do, the dftables.c source file is compiled and run on the local host, in order to generate the inbuilt character tables (the pcre_chartables.c file). This will probably not work, because dftables.c needs to be compiled with the local compiler, not the cross compiler. When --enable-rebuild-chartables is not specified, pcre_chartables.c is created by making a copy of pcre_chartables.c.dist, which is a default set of tables that assumes ASCII code. Cross-compiling with the default tables should not be a problem. If you need to modify the character tables when cross-compiling, you should move pcre_chartables.c.dist out of the way, then compile dftables.c by hand and run it on the local host to make a new version of pcre_chartables.c.dist. Then when you cross-compile PCRE this new version of the tables will be used. Using HP's ANSI C++ compiler (aCC) ---------------------------------- Unless C++ support is disabled by specifying the "--disable-cpp" option of the "configure" script, you must include the "-AA" option in the CXXFLAGS environment variable in order for the C++ components to compile correctly. Also, note that the aCC compiler on PA-RISC platforms may have a defect whereby needed libraries fail to get included when specifying the "-AA" compiler option. If you experience unresolved symbols when linking the C++ programs, use the workaround of specifying the following environment variable prior to running the "configure" script: CXXLDFLAGS="-lstd_v2 -lCsup_v2" Using Sun's compilers for Solaris --------------------------------- A user reports that the following configurations work on Solaris 9 sparcv9 and Solaris 9 x86 (32-bit): Solaris 9 sparcv9: ./configure --disable-cpp CC=/bin/cc CFLAGS="-m64 -g" Solaris 9 x86: ./configure --disable-cpp CC=/bin/cc CFLAGS="-g" Using PCRE from MySQL --------------------- On systems where both PCRE and MySQL are installed, it is possible to make use of PCRE from within MySQL, as an alternative to the built-in pattern matching. There is a web page that tells you how to do this: http://www.mysqludf.org/lib_mysqludf_preg/index.php Making new tarballs ------------------- The command "make dist" creates three PCRE tarballs, in tar.gz, tar.bz2, and zip formats. The command "make distcheck" does the same, but then does a trial build of the new distribution to ensure that it works. If you have modified any of the man page sources in the doc directory, you should first run the PrepareRelease script before making a distribution. This script creates the .txt and HTML forms of the documentation from the man pages. Testing PCRE ------------ To test the basic PCRE library on a Unix-like system, run the RunTest script. There is another script called RunGrepTest that tests the options of the pcregrep command. If the C++ wrapper library is built, three test programs called pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest are also built. When JIT support is enabled, another test program called pcre_jit_test is built. Both the scripts and all the program tests are run if you obey "make check" or "make test". For other environments, see the instructions in NON-AUTOTOOLS-BUILD. The RunTest script runs the pcretest test program (which is documented in its own man page) on each of the relevant testinput files in the testdata directory, and compares the output with the contents of the corresponding testoutput files. Some tests are relevant only when certain build-time options were selected. For example, the tests for UTF-8/16 support are run only if --enable-utf was used. RunTest outputs a comment when it skips a test. Many of the tests that are not skipped are run up to three times. The second run forces pcre_study() to be called for all patterns except for a few in some tests that are marked "never study" (see the pcretest program for how this is done). If JIT support is available, the non-DFA tests are run a third time, this time with a forced pcre_study() with the PCRE_STUDY_JIT_COMPILE option. When both 8-bit and 16-bit support is enabled, the entire set of tests is run twice, once for each library. If you want to run just one set of tests, call RunTest with either the -8 or -16 option. RunTest uses a file called testtry to hold the main output from pcretest. Other files whose names begin with "test" are used as working files in some tests. To run pcretest on just one or more specific test files, give their numbers as arguments to RunTest, for example: RunTest 2 7 11 You can also call RunTest with the single argument "list" to cause it to output a list of tests. The first test file can be fed directly into the perltest.pl script to check that Perl gives the same results. The only difference you should see is in the first few lines, where the Perl version is given instead of the PCRE version. The second set of tests check pcre_fullinfo(), pcre_study(), pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error detection, and run-time flags that are specific to PCRE, as well as the POSIX wrapper API. It also uses the debugging flags to check some of the internals of pcre_compile(). If you build PCRE with a locale setting that is not the standard C locale, the character tables may be different (see next paragraph). In some cases, this may cause failures in the second set of tests. For example, in a locale where the isprint() function yields TRUE for characters in the range 128-255, the use of [:isascii:] inside a character class defines a different set of characters, and this shows up in this test as a difference in the compiled code, which is being listed for checking. Where the comparison test output contains [\x00-\x7f] the test will contain [\x00-\xff], and similarly in some other cases. This is not a bug in PCRE. The third set of tests checks pcre_maketables(), the facility for building a set of character tables for a specific locale and using them instead of the default tables. The tests make use of the "fr_FR" (French) locale. Before running the test, the script checks for the presence of this locale by running the "locale" command. If that command fails, or if it doesn't include "fr_FR" in the list of available locales, the third test cannot be run, and a comment is output to say why. If running this test produces instances of the error ** Failed to set locale "fr_FR" in the comparison output, it means that locale is not available on your system, despite being listed by "locale". This does not mean that PCRE is broken. [If you are trying to run this test on Windows, you may be able to get it to work by changing "fr_FR" to "french" everywhere it occurs. Alternatively, use RunTest.bat. The version of RunTest.bat included with PCRE 7.4 and above uses Windows versions of test 2. More info on using RunTest.bat is included in the document entitled NON-UNIX-USE.] The fourth and fifth tests check the UTF-8/16 support and error handling and internal UTF features of PCRE that are not relevant to Perl, respectively. The sixth and seventh tests do the same for Unicode character properties support. The eighth, ninth, and tenth tests check the pcre_dfa_exec() alternative matching function, in non-UTF-8/16 mode, UTF-8/16 mode, and UTF-8/16 mode with Unicode property support, respectively. The eleventh test checks some internal offsets and code size features; it is run only when the default "link size" of 2 is set (in other cases the sizes change) and when Unicode property support is enabled. The twelfth test is run only when JIT support is available, and the thirteenth test is run only when JIT support is not available. They test some JIT-specific features such as information output from pcretest about JIT compilation. The fourteenth, fifteenth, and sixteenth tests are run only in 8-bit mode, and the seventeenth, eighteenth, and nineteenth tests are run only in 16-bit mode. These are tests that generate different output in the two modes. They are for general cases, UTF-8/16 support, and Unicode property support, respectively. The twentieth test is run only in 16-bit mode. It tests some specific 16-bit features of the DFA matching engine. The twenty-first and twenty-second tests are run only in 16-bit mode, when the link size is set to 2. They test reloading pre-compiled patterns. Character tables ---------------- For speed, PCRE uses four tables for manipulating and identifying characters whose code point values are less than 256. The final argument of the pcre_compile() function is a pointer to a block of memory containing the concatenated tables. A call to pcre_maketables() can be used to generate a set of tables in the current locale. If the final argument for pcre_compile() is passed as NULL, a set of default tables that is built into the binary is used. The source file called pcre_chartables.c contains the default set of tables. By default, this is created as a copy of pcre_chartables.c.dist, which contains tables for ASCII coding. However, if --enable-rebuild-chartables is specified for ./configure, a different version of pcre_chartables.c is built by the program dftables (compiled from dftables.c), which uses the ANSI C character handling functions such as isalnum(), isalpha(), isupper(), islower(), etc. to build the table sources. This means that the default C locale which is set for your system will control the contents of these default tables. You can change the default tables by editing pcre_chartables.c and then re-building PCRE. If you do this, you should take care to ensure that the file does not get automatically re-generated. The best way to do this is to move pcre_chartables.c.dist out of the way and replace it with your customized tables. When the dftables program is run as a result of --enable-rebuild-chartables, it uses the default C locale that is set on your system. It does not pay attention to the LC_xxx environment variables. In other words, it uses the system's default locale rather than whatever the compiling user happens to have set. If you really do want to build a source set of character tables in a locale that is specified by the LC_xxx variables, you can run the dftables program by hand with the -L option. For example: ./dftables -L pcre_chartables.c.special The first two 256-byte tables provide lower casing and case flipping functions, respectively. The next table consists of three 32-byte bit maps which identify digits, "word" characters, and white space, respectively. These are used when building 32-byte bit maps that represent character classes for code points less than 256. The final 256-byte table has bits indicating various character types, as follows: 1 white space character 2 letter 4 decimal digit 8 hexadecimal digit 16 alphanumeric or '_' 128 regular expression metacharacter or binary zero You should not alter the set of characters that contain the 128 bit, as that will cause PCRE to malfunction. File manifest ------------- The distribution should contain the files listed below. Where a file name is given as pcre[16]_xxx it means that there are two files, one with the name pcre_xxx and the other with the name pcre16_xxx. (A) Source files of the PCRE library functions and their headers: dftables.c auxiliary program for building pcre_chartables.c when --enable-rebuild-chartables is specified pcre_chartables.c.dist a default set of character tables that assume ASCII coding; used, unless --enable-rebuild-chartables is specified, by copying to pcre[16]_chartables.c pcreposix.c ) pcre[16]_byte_order.c ) pcre[16]_compile.c ) pcre[16]_config.c ) pcre[16]_dfa_exec.c ) pcre[16]_exec.c ) pcre[16]_fullinfo.c ) pcre[16]_get.c ) sources for the functions in the library, pcre[16]_globals.c ) and some internal functions that they use pcre[16]_jit_compile.c ) pcre[16]_maketables.c ) pcre[16]_newline.c ) pcre[16]_refcount.c ) pcre[16]_string_utils.c ) pcre[16]_study.c ) pcre[16]_tables.c ) pcre[16]_ucd.c ) pcre[16]_version.c ) pcre[16]_xclass.c ) pcre_ord2utf8.c ) pcre_valid_utf8.c ) pcre16_ord2utf16.c ) pcre16_utf16_utils.c ) pcre16_valid_utf16.c ) pcre[16]_printint.c ) debugging function that is used by pcretest, ) and can also be #included in pcre_compile() pcre.h.in template for pcre.h when built by "configure" pcreposix.h header for the external POSIX wrapper API pcre_internal.h header for internal use sljit/* 16 files that make up the JIT compiler ucp.h header for Unicode property handling config.h.in template for config.h, which is built by "configure" pcrecpp.h public header file for the C++ wrapper pcrecpparg.h.in template for another C++ header file pcre_scanner.h public header file for C++ scanner functions pcrecpp.cc ) pcre_scanner.cc ) source for the C++ wrapper library pcre_stringpiece.h.in template for pcre_stringpiece.h, the header for the C++ stringpiece functions pcre_stringpiece.cc source for the C++ stringpiece functions (B) Source files for programs that use PCRE: pcredemo.c simple demonstration of coding calls to PCRE pcregrep.c source of a grep utility that uses PCRE pcretest.c comprehensive test program (C) Auxiliary files: 132html script to turn "man" pages into HTML AUTHORS information about the author of PCRE ChangeLog log of changes to the code CleanTxt script to clean nroff output for txt man pages Detrail script to remove trailing spaces HACKING some notes about the internals of PCRE INSTALL generic installation instructions LICENCE conditions for the use of PCRE COPYING the same, using GNU's standard name Makefile.in ) template for Unix Makefile, which is built by ) "configure" Makefile.am ) the automake input that was used to create ) Makefile.in NEWS important changes in this release NON-UNIX-USE the previous name for NON-AUTOTOOLS-BUILD NON-AUTOTOOLS-BUILD notes on building PCRE without using autotools PrepareRelease script to make preparations for "make dist" README this file RunTest a Unix shell script for running tests RunGrepTest a Unix shell script for pcregrep tests aclocal.m4 m4 macros (generated by "aclocal") config.guess ) files used by libtool, config.sub ) used only when building a shared library configure a configuring shell script (built by autoconf) configure.ac ) the autoconf input that was used to build ) "configure" and config.h depcomp ) script to find program dependencies, generated by ) automake doc/*.3 man page sources for PCRE doc/*.1 man page sources for pcregrep and pcretest doc/index.html.src the base HTML page doc/html/* HTML documentation doc/pcre.txt plain text version of the man pages doc/pcretest.txt plain text documentation of test program doc/perltest.txt plain text documentation of Perl test program install-sh a shell script for installing files libpcre16.pc.in template for libpcre16.pc for pkg-config libpcre.pc.in template for libpcre.pc for pkg-config libpcreposix.pc.in template for libpcreposix.pc for pkg-config libpcrecpp.pc.in template for libpcrecpp.pc for pkg-config ltmain.sh file used to build a libtool script missing ) common stub for a few missing GNU programs while ) installing, generated by automake mkinstalldirs script for making install directories perltest.pl Perl test program pcre-config.in source of script which retains PCRE information pcre_jit_test.c test program for the JIT compiler pcrecpp_unittest.cc ) pcre_scanner_unittest.cc ) test programs for the C++ wrapper pcre_stringpiece_unittest.cc ) testdata/testinput* test data for main library tests testdata/testoutput* expected test results testdata/grep* input and output for pcregrep tests testdata/* other supporting test files (D) Auxiliary files for cmake support cmake/COPYING-CMAKE-SCRIPTS cmake/FindPackageHandleStandardArgs.cmake cmake/FindEditline.cmake cmake/FindReadline.cmake CMakeLists.txt config-cmake.h.in (E) Auxiliary files for VPASCAL makevp.bat makevp_c.txt makevp_l.txt pcregexp.pas (F) Auxiliary files for building PCRE "by hand" pcre.h.generic ) a version of the public PCRE header file ) for use in non-"configure" environments config.h.generic ) a version of config.h for use in non-"configure" ) environments (F) Miscellaneous RunTest.bat a script for running tests under Windows Philip Hazel Email local part: ph10 Email domain: cam.ac.uk Last updated: 18 June 2012 pcre-8.31/pcrecpp.cc0000644000222100022210000007741611704612077011272 00000000000000// Copyright (c) 2010, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include /* for SHRT_MIN, USHRT_MAX, etc */ #include /* for memcpy */ #include #include #include #include #include "pcrecpp_internal.h" #include "pcre.h" #include "pcrecpp.h" #include "pcre_stringpiece.h" namespace pcrecpp { // Maximum number of args we can set static const int kMaxArgs = 16; static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace // Special object that stands-in for no argument Arg RE::no_arg((void*)NULL); // This is for ABI compatibility with old versions of pcre (pre-7.6), // which defined a global no_arg variable instead of putting it in the // RE class. This works on GCC >= 3, at least. It definitely works // for ELF, but may not for other object formats (Mach-O, for // instance, does not support aliases.) We could probably have a more // inclusive test if we ever needed it. (Note that not only the // __attribute__ syntax, but also __USER_LABEL_PREFIX__, are // gnu-specific.) #if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) # define ULP_AS_STRING(x) ULP_AS_STRING_INTERNAL(x) # define ULP_AS_STRING_INTERNAL(x) #x # define USER_LABEL_PREFIX_STR ULP_AS_STRING(__USER_LABEL_PREFIX__) extern Arg no_arg __attribute__((alias(USER_LABEL_PREFIX_STR "_ZN7pcrecpp2RE6no_argE"))); #endif // If a regular expression has no error, its error_ field points here static const string empty_string; // If the user doesn't ask for any options, we just use this one static RE_Options default_options; void RE::Init(const string& pat, const RE_Options* options) { pattern_ = pat; if (options == NULL) { options_ = default_options; } else { options_ = *options; } error_ = &empty_string; re_full_ = NULL; re_partial_ = NULL; re_partial_ = Compile(UNANCHORED); if (re_partial_ != NULL) { re_full_ = Compile(ANCHOR_BOTH); } } void RE::Cleanup() { if (re_full_ != NULL) (*pcre_free)(re_full_); if (re_partial_ != NULL) (*pcre_free)(re_partial_); if (error_ != &empty_string) delete error_; } RE::~RE() { Cleanup(); } pcre* RE::Compile(Anchor anchor) { // First, convert RE_Options into pcre options int pcre_options = 0; pcre_options = options_.all_options(); // Special treatment for anchoring. This is needed because at // runtime pcre only provides an option for anchoring at the // beginning of a string (unless you use offset). // // There are three types of anchoring we want: // UNANCHORED Compile the original pattern, and use // a pcre unanchored match. // ANCHOR_START Compile the original pattern, and use // a pcre anchored match. // ANCHOR_BOTH Tack a "\z" to the end of the original pattern // and use a pcre anchored match. const char* compile_error; int eoffset; pcre* re; if (anchor != ANCHOR_BOTH) { re = pcre_compile(pattern_.c_str(), pcre_options, &compile_error, &eoffset, NULL); } else { // Tack a '\z' at the end of RE. Parenthesize it first so that // the '\z' applies to all top-level alternatives in the regexp. string wrapped = "(?:"; // A non-counting grouping operator wrapped += pattern_; wrapped += ")\\z"; re = pcre_compile(wrapped.c_str(), pcre_options, &compile_error, &eoffset, NULL); } if (re == NULL) { if (error_ == &empty_string) error_ = new string(compile_error); } return re; } /***** Matching interfaces *****/ bool RE::FullMatch(const StringPiece& text, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; return DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize); } bool RE::PartialMatch(const StringPiece& text, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; return DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize); } bool RE::Consume(StringPiece* input, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; if (DoMatchImpl(*input, ANCHOR_START, &consumed, args, n, vec, kVecSize)) { input->remove_prefix(consumed); return true; } else { return false; } } bool RE::FindAndConsume(StringPiece* input, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; if (DoMatchImpl(*input, UNANCHORED, &consumed, args, n, vec, kVecSize)) { input->remove_prefix(consumed); return true; } else { return false; } } bool RE::Replace(const StringPiece& rewrite, string *str) const { int vec[kVecSize]; int matches = TryMatch(*str, 0, UNANCHORED, true, vec, kVecSize); if (matches == 0) return false; string s; if (!Rewrite(&s, rewrite, *str, vec, matches)) return false; assert(vec[0] >= 0); assert(vec[1] >= 0); str->replace(vec[0], vec[1] - vec[0], s); 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. // Modified by PH to add PCRE_NEWLINE_ANY and PCRE_NEWLINE_ANYCRLF. 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| PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF)) { newline_mode = (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF| PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF)); } 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 if (newline == -1) newline_mode = PCRE_NEWLINE_ANY; else if (newline == -2) newline_mode = PCRE_NEWLINE_ANYCRLF; else assert(NULL == "Unexpected return value from pcre_config(NEWLINE)"); } return newline_mode; } int RE::GlobalReplace(const StringPiece& rewrite, string *str) const { int count = 0; int vec[kVecSize]; string out; int start = 0; bool last_match_was_empty_string = false; while (start <= static_cast(str->length())) { // If the previous match was for the empty string, we shouldn't // just match again: we'll match in the same way and get an // infinite loop. Instead, we do the match in a special way: // anchored -- to force another try at the same position -- // and with a flag saying that this time, ignore empty matches. // If this special match returns, that means there's a non-empty // match at this position as well, and we can continue. If not, // we do what perl does, and just advance by one. // Notice that perl prints '@@@' for this; // perl -le '$_ = "aa"; s/b*|aa/@/g; print' int matches; if (last_match_was_empty_string) { matches = TryMatch(*str, start, ANCHOR_START, false, vec, kVecSize); if (matches <= 0) { int matchend = start + 1; // advance one character. // 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. // Modified by PH to add ANY and ANYCRLF. if (matchend < static_cast(str->length()) && (*str)[start] == '\r' && (*str)[matchend] == '\n' && (NewlineMode(options_.all_options()) == PCRE_NEWLINE_CRLF || NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANY || NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANYCRLF)) { 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(str->length()) && ((*str)[matchend] & 0xc0) == 0x80) matchend++; } #endif if (start < static_cast(str->length())) out.append(*str, start, matchend - start); start = matchend; last_match_was_empty_string = false; continue; } } else { matches = TryMatch(*str, start, UNANCHORED, true, vec, kVecSize); if (matches <= 0) break; } int matchstart = vec[0], matchend = vec[1]; assert(matchstart >= start); assert(matchend >= matchstart); out.append(*str, start, matchstart - start); Rewrite(&out, rewrite, *str, vec, matches); start = matchend; count++; last_match_was_empty_string = (matchstart == matchend); } if (count == 0) return 0; if (start < static_cast(str->length())) out.append(*str, start, str->length() - start); swap(out, *str); return count; } bool RE::Extract(const StringPiece& rewrite, const StringPiece& text, string *out) const { int vec[kVecSize]; int matches = TryMatch(text, 0, UNANCHORED, true, vec, kVecSize); if (matches == 0) return false; out->erase(); return Rewrite(out, rewrite, text, vec, matches); } /*static*/ string RE::QuoteMeta(const StringPiece& unquoted) { string result; // Escape any ascii character not in [A-Za-z_0-9]. // // Note that it's legal to escape a character even if it has no // special meaning in a regular expression -- so this function does // that. (This also makes it identical to the perl function of the // same name; see `perldoc -f quotemeta`.) The one exception is // escaping NUL: rather than doing backslash + NUL, like perl does, // we do '\0', because pcre itself doesn't take embedded NUL chars. for (int ii = 0; ii < unquoted.size(); ++ii) { // Note that using 'isalnum' here raises the benchmark time from // 32ns to 58ns: if (unquoted[ii] == '\0') { result += "\\0"; } else if ((unquoted[ii] < 'a' || unquoted[ii] > 'z') && (unquoted[ii] < 'A' || unquoted[ii] > 'Z') && (unquoted[ii] < '0' || unquoted[ii] > '9') && unquoted[ii] != '_' && // If this is the part of a UTF8 or Latin1 character, we need // to copy this byte without escaping. Experimentally this is // what works correctly with the regexp library. !(unquoted[ii] & 128)) { result += '\\'; result += unquoted[ii]; } else { result += unquoted[ii]; } } return result; } /***** Actual matching and rewriting code *****/ int RE::TryMatch(const StringPiece& text, int startpos, Anchor anchor, bool empty_ok, int *vec, int vecsize) const { pcre* re = (anchor == ANCHOR_BOTH) ? re_full_ : re_partial_; if (re == NULL) { //fprintf(stderr, "Matching against invalid re: %s\n", error_->c_str()); return 0; } pcre_extra extra = { 0, 0, 0, 0, 0, 0 }; if (options_.match_limit() > 0) { extra.flags |= PCRE_EXTRA_MATCH_LIMIT; extra.match_limit = options_.match_limit(); } if (options_.match_limit_recursion() > 0) { extra.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra.match_limit_recursion = options_.match_limit_recursion(); } int options = 0; if (anchor != UNANCHORED) options |= PCRE_ANCHORED; if (!empty_ok) options |= PCRE_NOTEMPTY; int rc = pcre_exec(re, // The regular expression object &extra, (text.data() == NULL) ? "" : text.data(), text.size(), startpos, options, vec, vecsize); // Handle errors if (rc == PCRE_ERROR_NOMATCH) { return 0; } else if (rc < 0) { //fprintf(stderr, "Unexpected return code: %d when matching '%s'\n", // re, pattern_.c_str()); return 0; } else if (rc == 0) { // pcre_exec() returns 0 as a special case when the number of // capturing subpatterns exceeds the size of the vector. // When this happens, there is a match and the output vector // is filled, but we miss out on the positions of the extra subpatterns. rc = vecsize / 2; } return rc; } bool RE::DoMatchImpl(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const* args, int n, int* vec, int vecsize) const { assert((1 + n) * 3 <= vecsize); // results + PCRE workspace int matches = TryMatch(text, 0, anchor, true, vec, vecsize); assert(matches >= 0); // TryMatch never returns negatives if (matches == 0) return false; *consumed = vec[1]; if (n == 0 || args == NULL) { // We are not interested in results return true; } if (NumberOfCapturingGroups() < n) { // RE has fewer capturing groups than number of arg pointers passed in return false; } // If we got here, we must have matched the whole pattern. // We do not need (can not do) any more checks on the value of 'matches' here // -- see the comment for TryMatch. for (int i = 0; i < n; i++) { const int start = vec[2*(i+1)]; const int limit = vec[2*(i+1)+1]; if (!args[i]->Parse(text.data() + start, limit-start)) { // TODO: Should we indicate what the error was? return false; } } return true; } bool RE::DoMatch(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const args[], int n) const { assert(n >= 0); size_t const vecsize = (1 + n) * 3; // results + PCRE workspace // (as for kVecSize) int space[21]; // use stack allocation for small vecsize (common case) int* vec = vecsize <= 21 ? space : new int[vecsize]; bool retval = DoMatchImpl(text, anchor, consumed, args, n, vec, (int)vecsize); if (vec != space) delete [] vec; return retval; } bool RE::Rewrite(string *out, const StringPiece &rewrite, const StringPiece &text, int *vec, int veclen) const { for (const char *s = rewrite.data(), *end = s + rewrite.size(); s < end; s++) { int c = *s; if (c == '\\') { c = *++s; if (isdigit(c)) { int n = (c - '0'); if (n >= veclen) { //fprintf(stderr, requested group %d in regexp %.*s\n", // n, rewrite.size(), rewrite.data()); return false; } int start = vec[2 * n]; if (start >= 0) out->append(text.data() + start, vec[2 * n + 1] - start); } else if (c == '\\') { *out += '\\'; } else { //fprintf(stderr, "invalid rewrite pattern: %.*s\n", // rewrite.size(), rewrite.data()); return false; } } else { *out += c; } } return true; } // Return the number of capturing subpatterns, or -1 if the // regexp wasn't valid on construction. int RE::NumberOfCapturingGroups() const { if (re_partial_ == NULL) return -1; int result; int pcre_retval = pcre_fullinfo(re_partial_, // The regular expression object NULL, // We did not study the pattern PCRE_INFO_CAPTURECOUNT, &result); assert(pcre_retval == 0); return result; } /***** Parsers for various types *****/ bool Arg::parse_null(const char* str, int n, void* dest) { // We fail if somebody asked us to store into a non-NULL void* pointer return (dest == NULL); } bool Arg::parse_string(const char* str, int n, void* dest) { if (dest == NULL) return true; reinterpret_cast(dest)->assign(str, n); return true; } bool Arg::parse_stringpiece(const char* str, int n, void* dest) { if (dest == NULL) return true; reinterpret_cast(dest)->set(str, n); return true; } bool Arg::parse_char(const char* str, int n, void* dest) { if (n != 1) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = str[0]; return true; } bool Arg::parse_uchar(const char* str, int n, void* dest) { if (n != 1) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = str[0]; return true; } // Largest number spec that we are willing to parse static const int kMaxNumberLength = 32; // REQUIRES "buf" must have length at least kMaxNumberLength+1 // REQUIRES "n > 0" // Copies "str" into "buf" and null-terminates if necessary. // Returns one of: // a. "str" if no termination is needed // b. "buf" if the string was copied and null-terminated // c. "" if the input was invalid and has no hope of being parsed static const char* TerminateNumber(char* buf, const char* str, int n) { if ((n > 0) && isspace(*str)) { // We are less forgiving than the strtoxxx() routines and do not // allow leading spaces. return ""; } // See if the character right after the input text may potentially // look like a digit. if (isdigit(str[n]) || ((str[n] >= 'a') && (str[n] <= 'f')) || ((str[n] >= 'A') && (str[n] <= 'F'))) { if (n > kMaxNumberLength) return ""; // Input too big to be a valid number memcpy(buf, str, n); buf[n] = '\0'; return buf; } else { // We can parse right out of the supplied string, so return it. return str; } } bool Arg::parse_long_radix(const char* str, int n, void* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); char* end; errno = 0; long r = strtol(str, &end, radix); if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_ulong_radix(const char* str, int n, void* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); if (str[0] == '-') return false; // strtoul() on a negative number?! char* end; errno = 0; unsigned long r = strtoul(str, &end, radix); if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_short_radix(const char* str, int n, void* dest, int radix) { long r; if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range if (dest == NULL) return true; *(reinterpret_cast(dest)) = static_cast(r); return true; } bool Arg::parse_ushort_radix(const char* str, int n, void* dest, int radix) { unsigned long r; if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse if (r > USHRT_MAX) return false; // Out of range if (dest == NULL) return true; *(reinterpret_cast(dest)) = static_cast(r); return true; } bool Arg::parse_int_radix(const char* str, int n, void* dest, int radix) { long r; if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse if (r < INT_MIN || r > INT_MAX) return false; // Out of range if (dest == NULL) return true; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_uint_radix(const char* str, int n, void* dest, int radix) { unsigned long r; if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse if (r > UINT_MAX) return false; // Out of range if (dest == NULL) return true; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_longlong_radix(const char* str, int n, void* dest, int radix) { #ifndef HAVE_LONG_LONG return false; #else if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); char* end; errno = 0; #if defined HAVE_STRTOQ long long r = strtoq(str, &end, radix); #elif defined HAVE_STRTOLL long long r = strtoll(str, &end, radix); #elif defined HAVE__STRTOI64 long long r = _strtoi64(str, &end, radix); #elif defined HAVE_STRTOIMAX long long r = strtoimax(str, &end, radix); #else #error parse_longlong_radix: cannot convert input to a long-long #endif if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = r; return true; #endif /* HAVE_LONG_LONG */ } bool Arg::parse_ulonglong_radix(const char* str, int n, void* dest, int radix) { #ifndef HAVE_UNSIGNED_LONG_LONG return false; #else if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); if (str[0] == '-') return false; // strtoull() on a negative number?! char* end; errno = 0; #if defined HAVE_STRTOQ unsigned long long r = strtouq(str, &end, radix); #elif defined HAVE_STRTOLL unsigned long long r = strtoull(str, &end, radix); #elif defined HAVE__STRTOI64 unsigned long long r = _strtoui64(str, &end, radix); #elif defined HAVE_STRTOIMAX unsigned long long r = strtoumax(str, &end, radix); #else #error parse_ulonglong_radix: cannot convert input to a long-long #endif if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = r; return true; #endif /* HAVE_UNSIGNED_LONG_LONG */ } bool Arg::parse_double(const char* str, int n, void* dest) { if (n == 0) return false; static const int kMaxLength = 200; char buf[kMaxLength]; if (n >= kMaxLength) return false; memcpy(buf, str, n); buf[n] = '\0'; errno = 0; char* end; double r = strtod(buf, &end); if (end != buf + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_float(const char* str, int n, void* dest) { double r; if (!parse_double(str, n, &r)) return false; if (dest == NULL) return true; *(reinterpret_cast(dest)) = static_cast(r); return true; } #define DEFINE_INTEGER_PARSERS(name) \ bool Arg::parse_##name(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 10); \ } \ bool Arg::parse_##name##_hex(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 16); \ } \ bool Arg::parse_##name##_octal(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 8); \ } \ bool Arg::parse_##name##_cradix(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 0); \ } DEFINE_INTEGER_PARSERS(short) /* */ DEFINE_INTEGER_PARSERS(ushort) /* */ DEFINE_INTEGER_PARSERS(int) /* Don't use semicolons after these */ DEFINE_INTEGER_PARSERS(uint) /* statements because they can cause */ DEFINE_INTEGER_PARSERS(long) /* compiler warnings if the checking */ DEFINE_INTEGER_PARSERS(ulong) /* level is turned up high enough. */ DEFINE_INTEGER_PARSERS(longlong) /* */ DEFINE_INTEGER_PARSERS(ulonglong) /* */ #undef DEFINE_INTEGER_PARSERS } // namespace pcrecpp pcre-8.31/pcredemo.c0000644000222100022210000003624011723364061011255 00000000000000/************************************************* * PCRE DEMONSTRATION PROGRAM * *************************************************/ /* This is a demonstration program to illustrate the most straightforward ways of calling the PCRE regular expression library from a C program. See the pcresample documentation for a short discussion ("man pcresample" if you have the PCRE man pages installed). In Unix-like environments, if PCRE is installed in your standard system libraries, you should be able to compile this program using this command: gcc -Wall pcredemo.c -lpcre -o pcredemo If PCRE is not installed in a standard place, it is likely to be installed with support for the pkg-config mechanism. If you have pkg-config, you can compile this program using this command: gcc -Wall pcredemo.c `pkg-config --cflags --libs libpcre` -o pcredemo If you do not have pkg-config, you may have to use this: gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \ -R/usr/local/lib -lpcre -o pcredemo Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and library files for PCRE are installed on your system. Only some operating systems (e.g. Solaris) use the -R option. Building under Windows: If you want to statically link this program against a non-dll .a file, you must define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. So in this environment, uncomment the following line. */ /* #define PCRE_STATIC */ #include #include #include #define OVECCOUNT 30 /* should be a multiple of 3 */ int main(int argc, char **argv) { pcre *re; const char *error; char *pattern; char *subject; unsigned char *name_table; unsigned int option_bits; int erroffset; int find_all; int crlf_is_newline; int namecount; int name_entry_size; int ovector[OVECCOUNT]; int subject_length; int rc, i; int utf8; /************************************************************************** * First, sort out the command line. There is only one possible option at * * the moment, "-g" to request repeated matching to find all occurrences, * * like Perl's /g option. We set the variable find_all to a non-zero value * * if the -g option is present. Apart from that, there must be exactly two * * arguments. * **************************************************************************/ find_all = 0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-g") == 0) find_all = 1; else break; } /* After the options, we require exactly two arguments, which are the pattern, and the subject string. */ if (argc - i != 2) { printf("Two arguments required: a regex and a subject string\n"); return 1; } pattern = argv[i]; subject = argv[i+1]; subject_length = (int)strlen(subject); /************************************************************************* * Now we are going to compile the regular expression pattern, and handle * * and errors that are detected. * *************************************************************************/ re = pcre_compile( pattern, /* the pattern */ 0, /* default options */ &error, /* for error message */ &erroffset, /* for error offset */ NULL); /* use default character tables */ /* Compilation failed: print the error message and exit */ if (re == NULL) { printf("PCRE compilation failed at offset %d: %s\n", erroffset, error); return 1; } /************************************************************************* * If the compilation succeeded, we call PCRE again, in order to do a * * pattern match against the subject string. This does just ONE match. If * * further matching is needed, it will be done below. * *************************************************************************/ rc = pcre_exec( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ subject, /* the subject string */ subject_length, /* the length of the subject */ 0, /* start at offset 0 in the subject */ 0, /* default options */ ovector, /* output vector for substring information */ OVECCOUNT); /* number of elements in the output vector */ /* Matching failed: handle error cases */ if (rc < 0) { switch(rc) { case PCRE_ERROR_NOMATCH: printf("No match\n"); break; /* Handle other special cases if you like */ default: printf("Matching error %d\n", rc); break; } pcre_free(re); /* Release memory used for the compiled pattern */ return 1; } /* Match succeded */ printf("\nMatch succeeded at offset %d\n", ovector[0]); /************************************************************************* * We have found the first match within the subject string. If the output * * vector wasn't big enough, say so. Then output any substrings that were * * captured. * *************************************************************************/ /* The output vector wasn't big enough */ if (rc == 0) { rc = OVECCOUNT/3; printf("ovector only has room for %d captured substrings\n", rc - 1); } /* Show substrings stored in the output vector by number. Obviously, in a real application you might want to do things other than print them. */ for (i = 0; i < rc; i++) { char *substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; printf("%2d: %.*s\n", i, substring_length, substring_start); } /************************************************************************** * That concludes the basic part of this demonstration program. We have * * compiled a pattern, and performed a single match. The code that follows * * shows first how to access named substrings, and then how to code for * * repeated matches on the same subject. * **************************************************************************/ /* See if there are any named substrings, and if so, show them by name. First we have to extract the count of named parentheses from the pattern. */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMECOUNT, /* number of named substrings */ &namecount); /* where to put the answer */ if (namecount <= 0) printf("No named substrings\n"); else { unsigned char *tabptr; printf("Named substrings\n"); /* Before we can access the substrings, we must extract the table for translating names to numbers, and the size of each entry in the table. */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMETABLE, /* address of the table */ &name_table); /* where to put the answer */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ &name_entry_size); /* where to put the answer */ /* Now we can scan the table and, for each entry, print the number, the name, and the substring itself. */ tabptr = name_table; for (i = 0; i < namecount; i++) { int n = (tabptr[0] << 8) | tabptr[1]; printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); tabptr += name_entry_size; } } /************************************************************************* * If the "-g" option was given on the command line, we want to continue * * to search for additional matches in the subject string, in a similar * * way to the /g option in Perl. This turns out to be trickier than you * * might think because of the possibility of matching an empty string. * * What happens is as follows: * * * * If the previous match was NOT for an empty string, we can just start * * the next match at the end of the previous one. * * * * If the previous match WAS for an empty string, we can't do that, as it * * would lead to an infinite loop. Instead, a special call of pcre_exec() * * is made with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED flags set. * * The first of these tells PCRE that an empty string at the start of the * * subject is not a valid match; other possibilities must be tried. The * * second flag restricts PCRE to one match attempt at the initial string * * position. If this match succeeds, an alternative to the empty string * * match has been found, and we can print it and proceed round the loop, * * advancing by the length of whatever was found. If this match does not * * succeed, we still stay in the loop, advancing by just one character. * * In UTF-8 mode, which can be set by (*UTF8) in the pattern, this may be * * more than one byte. * * * * However, there is a complication concerned with newlines. When the * * newline convention is such that CRLF is a valid newline, we must * * advance by two characters rather than one. The newline convention can * * be set in the regex by (*CR), etc.; if not, we must find the default. * *************************************************************************/ if (!find_all) /* Check for -g */ { pcre_free(re); /* Release the memory used for the compiled pattern */ return 0; /* Finish unless -g was given */ } /* Before running the loop, check for UTF-8 and whether CRLF is a valid newline sequence. First, find the options with which the regex was compiled; extract the UTF-8 state, and mask off all but the newline options. */ (void)pcre_fullinfo(re, NULL, PCRE_INFO_OPTIONS, &option_bits); utf8 = option_bits & PCRE_UTF8; option_bits &= PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_CRLF| PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF; /* If no newline options were set, find the default newline convention from the build configuration. */ if (option_bits == 0) { int d; (void)pcre_config(PCRE_CONFIG_NEWLINE, &d); /* Note that these values are always the ASCII ones, even in EBCDIC environments. CR = 13, NL = 10. */ option_bits = (d == 13)? PCRE_NEWLINE_CR : (d == 10)? PCRE_NEWLINE_LF : (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF : (d == -2)? PCRE_NEWLINE_ANYCRLF : (d == -1)? PCRE_NEWLINE_ANY : 0; } /* See if CRLF is a valid newline sequence. */ crlf_is_newline = option_bits == PCRE_NEWLINE_ANY || option_bits == PCRE_NEWLINE_CRLF || option_bits == PCRE_NEWLINE_ANYCRLF; /* Loop for second and subsequent matches */ for (;;) { int options = 0; /* Normally no options */ int start_offset = ovector[1]; /* Start at end of previous match */ /* If the previous match was for an empty string, we are finished if we are at the end of the subject. Otherwise, arrange to run another match at the same point to see if a non-empty match can be found. */ if (ovector[0] == ovector[1]) { if (ovector[0] == subject_length) break; options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED; } /* Run the next matching operation */ rc = pcre_exec( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ subject, /* the subject string */ subject_length, /* the length of the subject */ start_offset, /* starting offset in the subject */ options, /* options */ ovector, /* output vector for substring information */ OVECCOUNT); /* number of elements in the output vector */ /* This time, a result of NOMATCH isn't an error. If the value in "options" is zero, it just means we have found all possible matches, so the loop ends. Otherwise, it means we have failed to find a non-empty-string match at a point where there was a previous empty-string match. In this case, we do what Perl does: advance the matching position by one character, and continue. We do this by setting the "end of previous match" offset, because that is picked up at the top of the loop as the point at which to start again. There are two complications: (a) When CRLF is a valid newline sequence, and the current position is just before it, advance by an extra byte. (b) Otherwise we must ensure that we skip an entire UTF-8 character if we are in UTF-8 mode. */ if (rc == PCRE_ERROR_NOMATCH) { if (options == 0) break; /* All matches found */ ovector[1] = start_offset + 1; /* Advance one byte */ if (crlf_is_newline && /* If CRLF is newline & */ start_offset < subject_length - 1 && /* we are at CRLF, */ subject[start_offset] == '\r' && subject[start_offset + 1] == '\n') ovector[1] += 1; /* Advance by one more. */ else if (utf8) /* Otherwise, ensure we */ { /* advance a whole UTF-8 */ while (ovector[1] < subject_length) /* character. */ { if ((subject[ovector[1]] & 0xc0) != 0x80) break; ovector[1] += 1; } } continue; /* Go round the loop again */ } /* Other matching errors are not recoverable. */ if (rc < 0) { printf("Matching error %d\n", rc); pcre_free(re); /* Release memory used for the compiled pattern */ return 1; } /* Match succeded */ printf("\nMatch succeeded again at offset %d\n", ovector[0]); /* The match succeeded, but the output vector wasn't big enough. */ if (rc == 0) { rc = OVECCOUNT/3; printf("ovector only has room for %d captured substrings\n", rc - 1); } /* As before, show substrings stored in the output vector by number, and then also any named substrings. */ for (i = 0; i < rc; i++) { char *substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; printf("%2d: %.*s\n", i, substring_length, substring_start); } if (namecount <= 0) printf("No named substrings\n"); else { unsigned char *tabptr = name_table; printf("Named substrings\n"); for (i = 0; i < namecount; i++) { int n = (tabptr[0] << 8) | tabptr[1]; printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); tabptr += name_entry_size; } } } /* End of loop to find second and subsequent matches */ printf("\n"); pcre_free(re); /* Release memory used for the compiled pattern */ return 0; } /* End of pcredemo.c */ pcre-8.31/makevp.bat0000644000222100022210000000426511055307044011264 00000000000000:: AH 20-12-06 modified for new PCRE-7.0 and VP/BCC :: PH 19-03-07 renamed !compile.txt and !linklib.txt as makevp-compile.txt and :: makevp-linklib.txt :: PH 26-03-07 re-renamed !compile.txt and !linklib.txt as makevp-c.txt and :: makevp-l.txt :: PH 29-03-07 hopefully the final rename to makevp_c and makevp_l :: AH 27.08.08 updated for new PCRE-7.7 :: required PCRE.H and CONFIG.H will be generated if not existing @echo off echo. echo Compiling PCRE with BORLAND C++ for VIRTUAL PASCAL echo. REM This file was contributed by Alexander Tokarev for building PCRE for use REM with Virtual Pascal. It has not been tested with the latest PCRE release. REM This file has been modified and extended to compile with newer PCRE releases REM by Stefan Weber (Angels Holocaust). REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH SET BORLAND=f:\bcc REM location of the TASM binaries, if compiling with the -B BCC switch SET TASM=f:\tasm SET PATH=%PATH%;%BORLAND%\bin;%TASM%\bin SET PCRE_VER=77 SET COMPILE_DEFAULTS=-DHAVE_CONFIG_H -DPCRE_STATIC -I%BORLAND%\include del pcre%PCRE_VER%.lib >nul 2>nul :: sh configure :: check for needed header files if not exist pcre.h copy pcre.h.generic pcre.h if not exist config.h copy config.h.generic config.h bcc32 -DDFTABLES %COMPILE_DEFAULTS% -L%BORLAND%\lib dftables.c IF ERRORLEVEL 1 GOTO ERROR :: dftables > chartables.c dftables pcre_chartables.c REM compile and link the PCRE library into lib: option -B for ASM compile works too bcc32 -a4 -c -RT- -y- -v- -u- -R- -Q- -X -d -fp -ff -P- -O2 -Oc -Ov -3 -w-8004 -w-8064 -w-8065 -w-8012 -UDFTABLES -DVPCOMPAT %COMPILE_DEFAULTS% @makevp_c.txt IF ERRORLEVEL 1 GOTO ERROR tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset *memcmp *strlen IF ERRORLEVEL 1 GOTO ERROR tlib pcre%PCRE_VER%.lib @makevp_l.txt +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj +memcmp.obj +strlen.obj IF ERRORLEVEL 1 GOTO ERROR del *.obj *.tds *.bak >nul 2>nul echo --- echo Now the library should be complete. Please check all messages above. echo Don't care for warnings, it's OK. goto END :ERROR echo --- echo Error while compiling PCRE. Aborting... pause goto END :END pcre-8.31/pcre_globals.c0000644000222100022210000000720411701354273012111 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains global variables that are exported by the PCRE library. PCRE is thread-clean and doesn't use any global variables in the normal sense. However, it calls memory allocation and freeing functions via the four indirections below, and it can optionally do callouts, using the fifth indirection. These values can be changed by the caller, but are shared between all threads. For MS Visual Studio and Symbian OS, there are problems in initializing these variables to non-local functions. In these cases, therefore, an indirection via a local function is used. Also, when compiling for Virtual Pascal, things are done differently, and global variables are not used. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" #if defined _MSC_VER || defined __SYMBIAN32__ static void* LocalPcreMalloc(size_t aSize) { return malloc(aSize); } static void LocalPcreFree(void* aPtr) { free(aPtr); } PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc; PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree; PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc; PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree; PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL; #elif !defined VPCOMPAT PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc; PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free; PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc; PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free; PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL; #endif /* End of pcre_globals.c */ pcre-8.31/ltmain.sh0000755000222100022210000105017111775524607011151 00000000000000 # libtool (GNU libtool) 2.4 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION=2.4 TIMESTAMP="" package_revision=1.3293 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${EGREP="grep -E"} : ${FGREP="grep -F"} : ${GREP="grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SED="sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=: for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -e 's/\([\\"]\)/\\\1/g' \ -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_apped perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 pcre-8.31/configure0000755000222100022210000224554611775524612011246 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for PCRE 8.31. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PCRE' PACKAGE_TARNAME='pcre' PACKAGE_VERSION='8.31' PACKAGE_STRING='PCRE 8.31' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="pcre.h.in" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS LIBBZ2 LIBZ DISTCHECK_CONFIGURE_FLAGS EXTRA_LIBPCRECPP_LDFLAGS EXTRA_LIBPCREPOSIX_LDFLAGS EXTRA_LIBPCRE16_LDFLAGS EXTRA_LIBPCRE_LDFLAGS PCRE_STATIC_CFLAG LIBREADLINE WITH_UTF_FALSE WITH_UTF_TRUE WITH_JIT_FALSE WITH_JIT_TRUE WITH_REBUILD_CHARTABLES_FALSE WITH_REBUILD_CHARTABLES_TRUE WITH_PCRE_CPP_FALSE WITH_PCRE_CPP_TRUE WITH_PCRE16_FALSE WITH_PCRE16_TRUE WITH_PCRE8_FALSE WITH_PCRE8_TRUE pcre_have_bits_type_traits pcre_have_type_traits pcre_have_ulong_long pcre_have_long_long enable_cpp enable_pcre16 enable_pcre8 PCRE_DATE PCRE_PRERELEASE PCRE_MINOR PCRE_MAJOR CXXCPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP SED LIBTOOL OBJDUMP DLLTOOL AS host_os host_vendor host_cpu host build_os build_vendor build_cpu build EGREP GREP CPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_pcre8 enable_pcre16 enable_cpp enable_jit enable_pcregrep_jit enable_rebuild_chartables enable_utf8 enable_utf enable_unicode_properties enable_newline_is_cr enable_newline_is_lf enable_newline_is_crlf enable_newline_is_anycrlf enable_newline_is_any enable_bsr_anycrlf enable_ebcdic enable_stack_for_recursion enable_pcregrep_libz enable_pcregrep_libbz2 with_pcregrep_bufsize enable_pcretest_libedit enable_pcretest_libreadline with_posix_malloc_threshold with_link_size with_match_limit with_match_limit_recursion ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures PCRE 8.31 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/pcre] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of PCRE 8.31:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0') --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-pcre8 disable 8 bit character support --enable-pcre16 enable 16 bit character support --disable-cpp disable C++ support --enable-jit enable Just-In-Time compiling support --disable-pcregrep-jit disable JIT support in pcregrep --enable-rebuild-chartables rebuild character tables in current locale --enable-utf8 another name for --enable-utf. Kept only for compatibility reasons --enable-utf enable UTF-8/16 support (incompatible with --enable-ebcdic) --enable-unicode-properties enable Unicode properties support (implies --enable-utf) --enable-newline-is-cr use CR as newline character --enable-newline-is-lf use LF as newline character (default) --enable-newline-is-crlf use CRLF as newline sequence --enable-newline-is-anycrlf use CR, LF, or CRLF as newline sequence --enable-newline-is-any use any valid Unicode newline sequence --enable-bsr-anycrlf \R matches only CR, LF, CRLF by default --enable-ebcdic assume EBCDIC coding rather than ASCII; incompatible with --enable-utf; use only in (uncommon) EBCDIC environments; it implies --enable-rebuild-chartables --disable-stack-for-recursion don't use stack recursion when matching --enable-pcregrep-libz link pcregrep with libz to handle .gz files --enable-pcregrep-libbz2 link pcregrep with libbz2 to handle .bz2 files --enable-pcretest-libedit link pcretest with libedit --enable-pcretest-libreadline link pcretest with libreadline Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-pcregrep-bufsize=N pcregrep buffer size (default=20480) --with-posix-malloc-threshold=NBYTES threshold for POSIX malloc usage (default=10) --with-link-size=N internal link size (2, 3, or 4 allowed; default=2) --with-match-limit=N default limit on internal looping (default=10000000) --with-match-limit-recursion=N default limit on internal recursion (default=MATCH_LIMIT) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF PCRE configure 8.31 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_find_intX_t LINENO BITS VAR # ----------------------------------- # Finds a signed integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_intX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in int$2_t 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else case $ac_type in #( int$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_intX_t # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES # --------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_cxx_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by PCRE $as_me 8.31, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='pcre' VERSION='8.31' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac AM_BACKSLASH='\' ac_config_headers="$ac_config_headers config.h" # This was added at the suggestion of libtoolize (03-Jan-10) # The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just # "-g" for any other compiler. There doesn't seem to be a standard way of # getting rid of the -g (which I don't think is needed for a production # library). This fudge seems to achieve the necessary. First, we remember the # externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and # AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not # set, they will be set to Autoconf's defaults. Afterwards, if the original # values were not set, remove the -g from the Autoconf defaults. # (PH 02-May-07) remember_set_CFLAGS="$CFLAGS" remember_set_CXXFLAGS="$CXXFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi if test "x$remember_set_CFLAGS" = "x" then if test "$CFLAGS" = "-g -O2" then CFLAGS="-O2" elif test "$CFLAGS" = "-g" then CFLAGS="" fi fi if test "x$remember_set_CXXFLAGS" = "x" then if test "$CXXFLAGS" = "-g -O2" then CXXFLAGS="-O2" elif test "$CXXFLAGS" = "-g" then CXXFLAGS="" fi fi # AC_PROG_CXX will return "g++" even if no c++ compiler is installed. # Check for that case, and just disable c++ code if g++ doesn't run. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else CXX=""; CXXCP=""; CXXFLAGS="" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check for a 64-bit integer type ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" case $ac_cv_c_int64_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int64_t $ac_cv_c_int64_t _ACEOF ;; esac # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 $as_echo "$AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 $as_echo "$ac_ct_AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4' macro_revision='1.3293' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf # Set options enable_dlopen=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' lt_prog_compiler_pic='-Xcompiler -fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ F* | *Sun*Fortran*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld='-rpath $libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; freebsd1*) ld_shlibs=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi # Handle Gentoo/FreeBSD as it was Linux case $host_vendor in gentoo) version_type=linux ;; *) version_type=freebsd-$objformat ;; esac case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; linux) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' need_lib_prefix=no need_version=no ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; haiku*) version_type=linux need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_flag_spec_ld_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec_CXX='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" if test "$lt_cv_apple_cc_single_mod" != "yes"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi else ld_shlibs_CXX=no fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd[12]*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; gnu*) ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi # Handle Gentoo/FreeBSD as it was Linux case $host_vendor in gentoo) version_type=linux ;; *) version_type=freebsd-$objformat ;; esac case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; linux) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' need_lib_prefix=no need_version=no ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; haiku*) version_type=linux need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi PCRE_MAJOR="8" PCRE_MINOR="31" PCRE_PRERELEASE="" PCRE_DATE="2012-07-06" if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09" then echo "***" echo "*** Minor version number $PCRE_MINOR must not be used. ***" echo "*** Use only 01 to 07 or 10 onwards, to avoid octal issues. ***" echo "***" exit 1 fi # Set a more sensible default value for $(htmldir). if test "x$htmldir" = 'x${docdir}' then htmldir='${docdir}/html' fi # Handle --disable-pcre8 (enabled by default) # Check whether --enable-pcre8 was given. if test "${enable_pcre8+set}" = set; then : enableval=$enable_pcre8; else enable_pcre8=unset fi # Handle --enable-pcre16 (disabled by default) # Check whether --enable-pcre16 was given. if test "${enable_pcre16+set}" = set; then : enableval=$enable_pcre16; else enable_pcre16=unset fi # Handle --disable-cpp. The substitution of enable_cpp is needed for use in # pcre-config. # Check whether --enable-cpp was given. if test "${enable_cpp+set}" = set; then : enableval=$enable_cpp; else enable_cpp=unset fi # Handle --enable-jit (disabled by default) # Check whether --enable-jit was given. if test "${enable_jit+set}" = set; then : enableval=$enable_jit; else enable_jit=no fi # Handle --disable-pcregrep-jit (enabled by default) # Check whether --enable-pcregrep-jit was given. if test "${enable_pcregrep_jit+set}" = set; then : enableval=$enable_pcregrep_jit; else enable_pcregrep_jit=yes fi # Handle --enable-rebuild-chartables # Check whether --enable-rebuild-chartables was given. if test "${enable_rebuild_chartables+set}" = set; then : enableval=$enable_rebuild_chartables; else enable_rebuild_chartables=no fi # Handle --enable-utf8 (disabled by default) # Check whether --enable-utf8 was given. if test "${enable_utf8+set}" = set; then : enableval=$enable_utf8; else enable_utf8=unset fi # Handle --enable-utf (disabled by default) # Check whether --enable-utf was given. if test "${enable_utf+set}" = set; then : enableval=$enable_utf; else enable_utf=unset fi # Handle --enable-unicode-properties # Check whether --enable-unicode-properties was given. if test "${enable_unicode_properties+set}" = set; then : enableval=$enable_unicode_properties; else enable_unicode_properties=no fi # Handle --enable-newline=NL # Separate newline options ac_pcre_newline=lf # Check whether --enable-newline-is-cr was given. if test "${enable_newline_is_cr+set}" = set; then : enableval=$enable_newline_is_cr; ac_pcre_newline=cr fi # Check whether --enable-newline-is-lf was given. if test "${enable_newline_is_lf+set}" = set; then : enableval=$enable_newline_is_lf; ac_pcre_newline=lf fi # Check whether --enable-newline-is-crlf was given. if test "${enable_newline_is_crlf+set}" = set; then : enableval=$enable_newline_is_crlf; ac_pcre_newline=crlf fi # Check whether --enable-newline-is-anycrlf was given. if test "${enable_newline_is_anycrlf+set}" = set; then : enableval=$enable_newline_is_anycrlf; ac_pcre_newline=anycrlf fi # Check whether --enable-newline-is-any was given. if test "${enable_newline_is_any+set}" = set; then : enableval=$enable_newline_is_any; ac_pcre_newline=any fi enable_newline="$ac_pcre_newline" # Handle --enable-bsr-anycrlf # Check whether --enable-bsr-anycrlf was given. if test "${enable_bsr_anycrlf+set}" = set; then : enableval=$enable_bsr_anycrlf; else enable_bsr_anycrlf=no fi # Handle --enable-ebcdic # Check whether --enable-ebcdic was given. if test "${enable_ebcdic+set}" = set; then : enableval=$enable_ebcdic; else enable_ebcdic=no fi # Handle --disable-stack-for-recursion # Check whether --enable-stack-for-recursion was given. if test "${enable_stack_for_recursion+set}" = set; then : enableval=$enable_stack_for_recursion; else enable_stack_for_recursion=yes fi # Handle --enable-pcregrep-libz # Check whether --enable-pcregrep-libz was given. if test "${enable_pcregrep_libz+set}" = set; then : enableval=$enable_pcregrep_libz; else enable_pcregrep_libz=no fi # Handle --enable-pcregrep-libbz2 # Check whether --enable-pcregrep-libbz2 was given. if test "${enable_pcregrep_libbz2+set}" = set; then : enableval=$enable_pcregrep_libbz2; else enable_pcregrep_libbz2=no fi # Handle --with-pcregrep-bufsize=N # Check whether --with-pcregrep-bufsize was given. if test "${with_pcregrep_bufsize+set}" = set; then : withval=$with_pcregrep_bufsize; else with_pcregrep_bufsize=20480 fi # Handle --enable-pcretest-libedit # Check whether --enable-pcretest-libedit was given. if test "${enable_pcretest_libedit+set}" = set; then : enableval=$enable_pcretest_libedit; else enable_pcretest_libedit=no fi # Handle --enable-pcretest-libreadline # Check whether --enable-pcretest-libreadline was given. if test "${enable_pcretest_libreadline+set}" = set; then : enableval=$enable_pcretest_libreadline; else enable_pcretest_libreadline=no fi # Handle --with-posix-malloc-threshold=NBYTES # Check whether --with-posix-malloc-threshold was given. if test "${with_posix_malloc_threshold+set}" = set; then : withval=$with_posix_malloc_threshold; else with_posix_malloc_threshold=10 fi # Handle --with-link-size=N # Check whether --with-link-size was given. if test "${with_link_size+set}" = set; then : withval=$with_link_size; else with_link_size=2 fi # Handle --with-match-limit=N # Check whether --with-match-limit was given. if test "${with_match_limit+set}" = set; then : withval=$with_match_limit; else with_match_limit=10000000 fi # Handle --with-match-limit_recursion=N # # Note: In config.h, the default is to define MATCH_LIMIT_RECURSION # symbolically as MATCH_LIMIT, which in turn is defined to be some numeric # value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some # different numeric value (or even the same numeric value as MATCH_LIMIT, # though no longer defined in terms of the latter). # # Check whether --with-match-limit-recursion was given. if test "${with_match_limit_recursion+set}" = set; then : withval=$with_match_limit_recursion; else with_match_limit_recursion=MATCH_LIMIT fi # Copy enable_utf8 value to enable_utf for compatibility reasons if test "x$enable_utf8" != "xunset" then if test "x$enable_utf" != "xunset" then as_fn_error $? "--enable/disable-utf8 is kept only for compatibility reasons and its value is copied to --enable/disable-utf. Newer code must use --enable/disable-utf alone." "$LINENO" 5 fi enable_utf=$enable_utf8 fi # Set the default value for pcre8 if test "x$enable_pcre8" = "xunset" then enable_pcre8=yes fi # Set the default value for pcre16 if test "x$enable_pcre16" = "xunset" then enable_pcre16=no fi # Make sure enable_pcre8 or enable_pcre16 was set if test "x$enable_pcre8$enable_pcre16" = "xnono" then as_fn_error $? "Either 8 or 16 bit (or both) pcre library must be enabled" "$LINENO" 5 fi # Make sure that if enable_unicode_properties was set, that UTF support is enabled. if test "x$enable_unicode_properties" = "xyes" then if test "x$enable_utf" = "xno" then as_fn_error $? "support for Unicode properties requires UTF-8/16 support" "$LINENO" 5 fi enable_utf=yes fi # enable_utf is disabled by default. if test "x$enable_utf" = "xunset" then enable_utf=no fi # enable_cpp copies the value of enable_pcre8 by default if test "x$enable_cpp" = "xunset" then enable_cpp=$enable_pcre8 fi # Make sure that if enable_cpp was set, that enable_pcre8 support is enabled if test "x$enable_cpp" = "xyes" then if test "x$enable_pcre8" = "xno" then as_fn_error $? "C++ library requires pcre library with 8 bit characters" "$LINENO" 5 fi fi # Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled. # Also check that UTF support is not requested, because PCRE cannot handle # EBCDIC and UTF in the same build. To do so it would need to use different # character constants depending on the mode. # if test "x$enable_ebcdic" = "xyes" then enable_rebuild_chartables=yes if test "x$enable_utf" = "xyes" then as_fn_error $? "support for EBCDIC and UTF-8/16 cannot be enabled at the same time" "$LINENO" 5 fi fi # Convert the newline identifier into the appropriate integer value. case "$enable_newline" in lf) ac_pcre_newline_value=10 ;; cr) ac_pcre_newline_value=13 ;; crlf) ac_pcre_newline_value=3338 ;; anycrlf) ac_pcre_newline_value=-2 ;; any) ac_pcre_newline_value=-1 ;; *) as_fn_error $? "invalid argument \"$enable_newline\" to --enable-newline option" "$LINENO" 5 ;; esac # Check argument to --with-link-size case "$with_link_size" in 2|3|4) ;; *) as_fn_error $? "invalid argument \"$with_link_size\" to --with-link-size option" "$LINENO" 5 ;; esac # Checks for header files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in limits.h sys/types.h sys/stat.h dirent.h windows.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # The files below are C++ header files. pcre_have_type_traits="0" pcre_have_bits_type_traits="0" if test "x$enable_cpp" = "xyes" -a -n "$CXX" then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # Older versions of pcre defined pcrecpp::no_arg, but in new versions # it's called pcrecpp::RE::no_arg. For backwards ABI compatibility, # we want to make one an alias for the other. Different systems do # this in different ways. Some systems, for instance, can do it via # a linker flag: -alias (for os x 10.5) or -i (for os x <=10.4). OLD_LDFLAGS="$LDFLAGS" for flag in "-alias,__ZN7pcrecpp2RE6no_argE,__ZN7pcrecpp6no_argE" \ "-i__ZN7pcrecpp6no_argE:__ZN7pcrecpp2RE6no_argE"; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alias support in the linker" >&5 $as_echo_n "checking for alias support in the linker... " >&6; } LDFLAGS="$OLD_LDFLAGS -Wl,$flag" # We try to run the linker with this new ld flag. If the link fails, # we give up and remove the new flag from LDFLAGS. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace pcrecpp { class RE { static int no_arg; }; int RE::no_arg; } int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS -Wl,$flag"; break; else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LDFLAGS="$OLD_LDFLAGS" # We could be more clever here, given we're doing AC_SUBST with this # (eg set a var to be the name of the include file we want). But we're not # so it's easy to change back to 'regular' autoconf vars if we needed to. for ac_header in string do : ac_fn_cxx_check_header_mongrel "$LINENO" "string" "ac_cv_header_string" "$ac_includes_default" if test "x$ac_cv_header_string" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRING 1 _ACEOF pcre_have_cpp_headers="1" else pcre_have_cpp_headers="0" fi done for ac_header in bits/type_traits.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "bits/type_traits.h" "ac_cv_header_bits_type_traits_h" "$ac_includes_default" if test "x$ac_cv_header_bits_type_traits_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BITS_TYPE_TRAITS_H 1 _ACEOF pcre_have_bits_type_traits="1" else pcre_have_bits_type_traits="0" fi done for ac_header in type_traits.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "type_traits.h" "ac_cv_header_type_traits_h" "$ac_includes_default" if test "x$ac_cv_header_type_traits_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TYPE_TRAITS_H 1 _ACEOF pcre_have_type_traits="1" else pcre_have_type_traits="0" fi done # (This isn't c++-specific, but is only used in pcrecpp.cc, so try this # in a c++ context. This matters becuase strtoimax is C99 and may not # be supported by the C++ compiler.) # Figure out how to create a longlong from a string: strtoll and # equiv. It's not enough to call AC_CHECK_FUNCS: hpux has a # strtoll, for instance, but it only takes 2 args instead of 3! # We have to call AH_TEMPLATE since AC_DEFINE_UNQUOTED below is complex. have_strto_fn=0 for fn in strtoq strtoll _strtoi64 strtoimax; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $fn" >&5 $as_echo_n "checking for $fn... " >&6; } if test "$fn" = strtoimax; then include=stdint.h else include=stdlib.h fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$include> int main () { char* e; return $fn("100", &e, 10) ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_`echo $fn | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` 1 _ACEOF have_strto_fn=1 break else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done if test "$have_strto_fn" = 1; then ac_fn_cxx_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" if test "x$ac_cv_type_long_long" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LONG_LONG 1 _ACEOF pcre_have_long_long="1" else pcre_have_long_long="0" fi ac_fn_cxx_check_type "$LINENO" "unsigned long long" "ac_cv_type_unsigned_long_long" "$ac_includes_default" if test "x$ac_cv_type_unsigned_long_long" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNSIGNED_LONG_LONG 1 _ACEOF pcre_have_ulong_long="1" else pcre_have_ulong_long="0" fi else pcre_have_long_long="0" pcre_have_ulong_long="0" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi # Using AC_SUBST eliminates the need to include config.h in a public .h file # Conditional compilation if test "x$enable_pcre8" = "xyes"; then WITH_PCRE8_TRUE= WITH_PCRE8_FALSE='#' else WITH_PCRE8_TRUE='#' WITH_PCRE8_FALSE= fi if test "x$enable_pcre16" = "xyes"; then WITH_PCRE16_TRUE= WITH_PCRE16_FALSE='#' else WITH_PCRE16_TRUE='#' WITH_PCRE16_FALSE= fi if test "x$enable_cpp" = "xyes"; then WITH_PCRE_CPP_TRUE= WITH_PCRE_CPP_FALSE='#' else WITH_PCRE_CPP_TRUE='#' WITH_PCRE_CPP_FALSE= fi if test "x$enable_rebuild_chartables" = "xyes"; then WITH_REBUILD_CHARTABLES_TRUE= WITH_REBUILD_CHARTABLES_FALSE='#' else WITH_REBUILD_CHARTABLES_TRUE='#' WITH_REBUILD_CHARTABLES_FALSE= fi if test "x$enable_jit" = "xyes"; then WITH_JIT_TRUE= WITH_JIT_FALSE='#' else WITH_JIT_TRUE='#' WITH_JIT_FALSE= fi if test "x$enable_utf" = "xyes"; then WITH_UTF_TRUE= WITH_UTF_FALSE='#' else WITH_UTF_TRUE='#' WITH_UTF_FALSE= fi # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # Checks for library functions. for ac_func in bcopy memmove strerror do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # Check for the availability of libz (aka zlib) for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF HAVE_ZLIB_H=1 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 $as_echo_n "checking for gzopen in -lz... " >&6; } if ${ac_cv_lib_z_gzopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gzopen (); int main () { return gzopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_gzopen=yes else ac_cv_lib_z_gzopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5 $as_echo "$ac_cv_lib_z_gzopen" >&6; } if test "x$ac_cv_lib_z_gzopen" = xyes; then : HAVE_LIBZ=1 fi # Check for the availability of libbz2. Originally we just used AC_CHECK_LIB, # as for libz. However, this had the following problem, diagnosed and fixed by # a user: # # - libbz2 uses the Pascal calling convention (WINAPI) for the functions # under Win32. # - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", # therefore missing the function definition. # - The compiler thus generates a "C" signature for the test function. # - The linker fails to find the "C" function. # - PCRE fails to configure if asked to do so against libbz2. # # Solution: # # - Replace the AC_CHECK_LIB test with a custom test. for ac_header in bzlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" if test "x$ac_cv_header_bzlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BZLIB_H 1 _ACEOF HAVE_BZLIB_H=1 fi done # Original test # AC_CHECK_LIB([bz2], [BZ2_bzopen], [HAVE_LIBBZ2=1]) # # Custom test follows { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libbz2" >&5 $as_echo_n "checking for libbz2... " >&6; } OLD_LIBS="$LIBS" LIBS="$LIBS -lbz2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_BZLIB_H #include #endif int main () { return (int)BZ2_bzopen("conftest", "rb"); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };HAVE_LIBBZ2=1; break; else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$OLD_LIBS" # Check for the availabiity of libreadline if test "$enable_pcretest_libreadline" = "yes"; then for ac_header in readline/readline.h do : ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" if test "x$ac_cv_header_readline_readline_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE_READLINE_H 1 _ACEOF HAVE_READLINE_H=1 fi done for ac_header in readline/history.h do : ac_fn_c_check_header_mongrel "$LINENO" "readline/history.h" "ac_cv_header_readline_history_h" "$ac_includes_default" if test "x$ac_cv_header_readline_history_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE_HISTORY_H 1 _ACEOF HAVE_HISTORY_H=1 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : LIBREADLINE="-lreadline" else unset ac_cv_lib_readline_readline; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline -ltinfo $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : LIBREADLINE="-ltinfo" else unset ac_cv_lib_readline_readline; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline -lcurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : LIBREADLINE="-lcurses" else unset ac_cv_lib_readline_readline; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline -lncurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : LIBREADLINE="-lncurses" else unset ac_cv_lib_readline_readline; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline -lncursesw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : LIBREADLINE="-lncursesw" else unset ac_cv_lib_readline_readline; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline -ltermcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : LIBREADLINE="-ltermcap" else LIBREADLINE="" fi fi fi fi fi fi if test -n "$LIBREADLINE"; then if test "$LIBREADLINE" != "-lreadline"; then echo "-lreadline needs $LIBREADLINE" LIBREADLINE="-lreadline $LIBREADLINE" fi fi fi # Check for the availability of libedit. Different distributions put its # headers in different places. Try to cover the most common ones. if test "$enable_pcretest_libedit" = "yes"; then for ac_header in editline/readline.h do : ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" if test "x$ac_cv_header_editline_readline_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_EDITLINE_READLINE_H 1 _ACEOF HAVE_EDITLINE_READLINE_H=1 else for ac_header in edit/readline/readline.h do : ac_fn_c_check_header_mongrel "$LINENO" "edit/readline/readline.h" "ac_cv_header_edit_readline_readline_h" "$ac_includes_default" if test "x$ac_cv_header_edit_readline_readline_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_EDIT_READLINE_READLINE_H 1 _ACEOF HAVE_READLINE_READLINE_H=1 else for ac_header in readline/readline.h do : ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" if test "x$ac_cv_header_readline_readline_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE_READLINE_H 1 _ACEOF HAVE_READLINE_READLINE_H=1 fi done fi done fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 $as_echo_n "checking for readline in -ledit... " >&6; } if ${ac_cv_lib_edit_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ledit $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_edit_readline=yes else ac_cv_lib_edit_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 $as_echo "$ac_cv_lib_edit_readline" >&6; } if test "x$ac_cv_lib_edit_readline" = xyes; then : LIBEDIT="-ledit" fi fi # This facilitates -ansi builds under Linux PCRE_STATIC_CFLAG="" if test "x$enable_shared" = "xno" ; then $as_echo "#define PCRE_STATIC 1" >>confdefs.h PCRE_STATIC_CFLAG="-DPCRE_STATIC" fi # Here is where pcre specific defines are handled if test "$enable_pcre8" = "yes"; then $as_echo "#define SUPPORT_PCRE8 /**/" >>confdefs.h fi if test "$enable_pcre16" = "yes"; then $as_echo "#define SUPPORT_PCRE16 /**/" >>confdefs.h fi if test "$enable_jit" = "yes"; then $as_echo "#define SUPPORT_JIT /**/" >>confdefs.h else enable_pcregrep_jit="no" fi if test "$enable_pcregrep_jit" = "yes"; then $as_echo "#define SUPPORT_PCREGREP_JIT /**/" >>confdefs.h fi if test "$enable_utf" = "yes"; then $as_echo "#define SUPPORT_UTF /**/" >>confdefs.h fi if test "$enable_unicode_properties" = "yes"; then $as_echo "#define SUPPORT_UCP /**/" >>confdefs.h fi if test "$enable_stack_for_recursion" = "no"; then $as_echo "#define NO_RECURSE /**/" >>confdefs.h fi if test "$enable_pcregrep_libz" = "yes"; then $as_echo "#define SUPPORT_LIBZ /**/" >>confdefs.h fi if test "$enable_pcregrep_libbz2" = "yes"; then $as_echo "#define SUPPORT_LIBBZ2 /**/" >>confdefs.h fi if test $with_pcregrep_bufsize -lt 8192 ; then with_pcregrep_bufsize="8192" fi cat >>confdefs.h <<_ACEOF #define PCREGREP_BUFSIZE $with_pcregrep_bufsize _ACEOF if test "$enable_pcretest_libedit" = "yes"; then $as_echo "#define SUPPORT_LIBEDIT /**/" >>confdefs.h LIBREADLINE="$LIBEDIT" elif test "$enable_pcretest_libreadline" = "yes"; then $as_echo "#define SUPPORT_LIBREADLINE /**/" >>confdefs.h fi cat >>confdefs.h <<_ACEOF #define NEWLINE $ac_pcre_newline_value _ACEOF if test "$enable_bsr_anycrlf" = "yes"; then $as_echo "#define BSR_ANYCRLF /**/" >>confdefs.h fi cat >>confdefs.h <<_ACEOF #define LINK_SIZE $with_link_size _ACEOF cat >>confdefs.h <<_ACEOF #define POSIX_MALLOC_THRESHOLD $with_posix_malloc_threshold _ACEOF cat >>confdefs.h <<_ACEOF #define MATCH_LIMIT $with_match_limit _ACEOF cat >>confdefs.h <<_ACEOF #define MATCH_LIMIT_RECURSION $with_match_limit_recursion _ACEOF $as_echo "#define MAX_NAME_SIZE 32" >>confdefs.h $as_echo "#define MAX_NAME_COUNT 10000" >>confdefs.h if test "$enable_ebcdic" = "yes"; then cat >>confdefs.h <<_ACEOF #define EBCDIC /**/ _ACEOF fi # Platform specific issues NO_UNDEFINED= EXPORT_ALL_SYMBOLS= case $host_os in cygwin* | mingw* ) if test X"$enable_shared" = Xyes; then NO_UNDEFINED="-no-undefined" EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" fi ;; esac # The extra LDFLAGS for each particular library # (Note: The libpcre*_version bits are m4 variables, assigned above) EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ $NO_UNDEFINED -version-info 1:1:0" EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ $NO_UNDEFINED -version-info 0:1:0" EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ $NO_UNDEFINED -version-info 0:1:0" EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ $NO_UNDEFINED -version-info 0:0:0 \ $EXPORT_ALL_SYMBOLS" # When we run 'make distcheck', use these arguments. Turning off compiler # optimization makes it run faster. DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre16 --enable-jit --enable-cpp --enable-unicode-properties" # Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is # specified, the relevant library is available. if test "$enable_pcregrep_libz" = "yes"; then if test "$HAVE_ZLIB_H" != "1"; then echo "** Cannot --enable-pcregrep-libz because zlib.h was not found" exit 1 fi if test "$HAVE_LIBZ" != "1"; then echo "** Cannot --enable-pcregrep-libz because libz was not found" exit 1 fi LIBZ="-lz" fi if test "$enable_pcregrep_libbz2" = "yes"; then if test "$HAVE_BZLIB_H" != "1"; then echo "** Cannot --enable-pcregrep-libbz2 because bzlib.h was not found" exit 1 fi if test "$HAVE_LIBBZ2" != "1"; then echo "** Cannot --enable-pcregrep-libbz2 because libbz2 was not found" exit 1 fi LIBBZ2="-lbz2" fi # Similarly for --enable-pcretest-readline if test "$enable_pcretest_libedit" = "yes"; then if test "$enable_pcretest_libreadline" = "yes"; then echo "** Cannot use both --enable-pcretest-libedit and --enable-pcretest-readline" exit 1 fi if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ "$HAVE_READLINE_READLINE_H" != "1"; then echo "** Cannot --enable-pcretest-libedit because neither editline/readline.h" echo "** nor readline/readline.h was found." exit 1 fi if test -z "$LIBEDIT"; then echo "** Cannot --enable-pcretest-libedit because libedit library was not found." exit 1 fi fi if test "$enable_pcretest_libreadline" = "yes"; then if test "$HAVE_READLINE_H" != "1"; then echo "** Cannot --enable-pcretest-readline because readline/readline.h was not found." exit 1 fi if test "$HAVE_HISTORY_H" != "1"; then echo "** Cannot --enable-pcretest-readline because readline/history.h was not found." exit 1 fi if test -z "$LIBREADLINE"; then echo "** Cannot --enable-pcretest-readline because readline library was not found." exit 1 fi fi # Produce these files, in addition to config.h. ac_config_files="$ac_config_files Makefile libpcre.pc libpcre16.pc libpcreposix.pc libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h" # Make the generated script files executable. ac_config_commands="$ac_config_commands script-chmod" # Make sure that pcre_chartables.c is removed in case the method for # creating it was changed by reconfiguration. ac_config_commands="$ac_config_commands delete-old-chartables" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_PCRE8_TRUE}" && test -z "${WITH_PCRE8_FALSE}"; then as_fn_error $? "conditional \"WITH_PCRE8\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_PCRE16_TRUE}" && test -z "${WITH_PCRE16_FALSE}"; then as_fn_error $? "conditional \"WITH_PCRE16\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_PCRE_CPP_TRUE}" && test -z "${WITH_PCRE_CPP_FALSE}"; then as_fn_error $? "conditional \"WITH_PCRE_CPP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_REBUILD_CHARTABLES_TRUE}" && test -z "${WITH_REBUILD_CHARTABLES_FALSE}"; then as_fn_error $? "conditional \"WITH_REBUILD_CHARTABLES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_JIT_TRUE}" && test -z "${WITH_JIT_FALSE}"; then as_fn_error $? "conditional \"WITH_JIT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_UTF_TRUE}" && test -z "${WITH_UTF_FALSE}"; then as_fn_error $? "conditional \"WITH_UTF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by PCRE $as_me 8.31, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ PCRE config.status 8.31 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in AS \ DLLTOOL \ OBJDUMP \ SHELL \ ECHO \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libpcre.pc") CONFIG_FILES="$CONFIG_FILES libpcre.pc" ;; "libpcre16.pc") CONFIG_FILES="$CONFIG_FILES libpcre16.pc" ;; "libpcreposix.pc") CONFIG_FILES="$CONFIG_FILES libpcreposix.pc" ;; "libpcrecpp.pc") CONFIG_FILES="$CONFIG_FILES libpcrecpp.pc" ;; "pcre-config") CONFIG_FILES="$CONFIG_FILES pcre-config" ;; "pcre.h") CONFIG_FILES="$CONFIG_FILES pcre.h" ;; "pcre_stringpiece.h") CONFIG_FILES="$CONFIG_FILES pcre_stringpiece.h" ;; "pcrecpparg.h") CONFIG_FILES="$CONFIG_FILES pcrecpparg.h" ;; "script-chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS script-chmod" ;; "delete-old-chartables") CONFIG_COMMANDS="$CONFIG_COMMANDS delete-old-chartables" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010 Free Software Foundation, # Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Assembler program. AS=$lt_AS # DLL creation program. DLLTOOL=$lt_DLLTOOL # Object dumper program. OBJDUMP=$lt_OBJDUMP # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; "script-chmod":C) chmod a+x pcre-config ;; "delete-old-chartables":C) rm -f pcre_chartables.c ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi # Print out a nice little message after configure is run displaying your # chosen options. cat < #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef SUPPORT_LIBZ #include #endif #ifdef SUPPORT_LIBBZ2 #include #endif #include "pcre.h" #define FALSE 0 #define TRUE 1 typedef int BOOL; #define MAX_PATTERN_COUNT 100 #define OFFSET_SIZE 99 #if BUFSIZ > 8192 #define PATBUFSIZE BUFSIZ #else #define PATBUFSIZE 8192 #endif /* Values for the "filenames" variable, which specifies options for file name output. The order is important; it is assumed that a file name is wanted for all values greater than FN_DEFAULT. */ enum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE }; /* File reading styles */ enum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 }; /* Actions for the -d and -D options */ enum { dee_READ, dee_SKIP, dee_RECURSE }; enum { DEE_READ, DEE_SKIP }; /* Actions for special processing options (flag bits) */ #define PO_WORD_MATCH 0x0001 #define PO_LINE_MATCH 0x0002 #define PO_FIXED_STRINGS 0x0004 /* Line ending types */ enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF }; /* Binary file options */ enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT }; /* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some environments), a warning is issued if the value of fwrite() is ignored. Unfortunately, casting to (void) does not suppress the warning. To get round this, we use a macro that compiles a fudge. Oddly, this does not also seem to apply to fprintf(). */ #define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {} /************************************************* * Global variables * *************************************************/ /* Jeffrey Friedl has some debugging requirements that are not part of the regular code. */ #ifdef JFRIEDL_DEBUG static int S_arg = -1; static unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */ static unsigned int jfriedl_XT = 0; /* replicate text this many times */ static const char *jfriedl_prefix = ""; static const char *jfriedl_postfix = ""; #endif static int endlinetype; static char *colour_string = (char *)"1;31"; static char *colour_option = NULL; static char *dee_option = NULL; static char *DEE_option = NULL; static char *main_buffer = NULL; static char *newline = NULL; static char *pattern_filename = NULL; static char *stdin_name = (char *)"(standard input)"; static char *locale = NULL; static const unsigned char *pcretables = NULL; static int pattern_count = 0; static pcre **pattern_list = NULL; static pcre_extra **hints_list = NULL; static char *file_list = NULL; static char *include_pattern = NULL; static char *exclude_pattern = NULL; static char *include_dir_pattern = NULL; static char *exclude_dir_pattern = NULL; static pcre *include_compiled = NULL; static pcre *exclude_compiled = NULL; static pcre *include_dir_compiled = NULL; static pcre *exclude_dir_compiled = NULL; static int after_context = 0; static int before_context = 0; static int binary_files = BIN_BINARY; static int both_context = 0; static int bufthird = PCREGREP_BUFSIZE; static int bufsize = 3*PCREGREP_BUFSIZE; static int dee_action = dee_READ; static int DEE_action = DEE_READ; static int error_count = 0; static int filenames = FN_DEFAULT; static int only_matching = -1; static int process_options = 0; #ifdef SUPPORT_PCREGREP_JIT static int study_options = PCRE_STUDY_JIT_COMPILE; #else static int study_options = 0; #endif static unsigned long int match_limit = 0; static unsigned long int match_limit_recursion = 0; static BOOL count_only = FALSE; static BOOL do_colour = FALSE; static BOOL file_offsets = FALSE; static BOOL hyphenpending = FALSE; static BOOL invert = FALSE; static BOOL line_buffered = FALSE; static BOOL line_offsets = FALSE; static BOOL multiline = FALSE; static BOOL number = FALSE; static BOOL omit_zero_count = FALSE; static BOOL resource_error = FALSE; static BOOL quiet = FALSE; static BOOL silent = FALSE; static BOOL utf8 = FALSE; /* Structure for options and list of them */ enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER, OP_OP_NUMBER, OP_PATLIST, OP_BINFILES }; typedef struct option_item { int type; int one_char; void *dataptr; const char *long_name; const char *help_text; } option_item; /* Options without a single-letter equivalent get a negative value. This can be used to identify them. */ #define N_COLOUR (-1) #define N_EXCLUDE (-2) #define N_EXCLUDE_DIR (-3) #define N_HELP (-4) #define N_INCLUDE (-5) #define N_INCLUDE_DIR (-6) #define N_LABEL (-7) #define N_LOCALE (-8) #define N_NULL (-9) #define N_LOFFSETS (-10) #define N_FOFFSETS (-11) #define N_LBUFFER (-12) #define N_M_LIMIT (-13) #define N_M_LIMIT_REC (-14) #define N_BUFSIZE (-15) #define N_NOJIT (-16) #define N_FILE_LIST (-17) #define N_BINARY_FILES (-18) static option_item optionlist[] = { { OP_NODATA, N_NULL, NULL, "", "terminate options" }, { OP_NODATA, N_HELP, NULL, "help", "display this help and exit" }, { OP_NUMBER, 'A', &after_context, "after-context=number", "set number of following context lines" }, { OP_NODATA, 'a', NULL, "text", "treat binary files as text" }, { OP_NUMBER, 'B', &before_context, "before-context=number", "set number of prior context lines" }, { OP_BINFILES, N_BINARY_FILES, NULL, "binary-files=word", "set treatment of binary files" }, { OP_NUMBER, N_BUFSIZE,&bufthird, "buffer-size=number", "set processing buffer size parameter" }, { OP_OP_STRING, N_COLOUR, &colour_option, "color=option", "matched text color option" }, { OP_OP_STRING, N_COLOUR, &colour_option, "colour=option", "matched text colour option" }, { OP_NUMBER, 'C', &both_context, "context=number", "set number of context lines, before & after" }, { OP_NODATA, 'c', NULL, "count", "print only a count of matching lines per FILE" }, { OP_STRING, 'D', &DEE_option, "devices=action","how to handle devices, FIFOs, and sockets" }, { OP_STRING, 'd', &dee_option, "directories=action", "how to handle directories" }, { OP_PATLIST, 'e', NULL, "regex(p)=pattern", "specify pattern (may be used more than once)" }, { OP_NODATA, 'F', NULL, "fixed-strings", "patterns are sets of newline-separated strings" }, { OP_STRING, 'f', &pattern_filename, "file=path", "read patterns from file" }, { OP_STRING, N_FILE_LIST, &file_list, "file-list=path","read files to search from file" }, { OP_NODATA, N_FOFFSETS, NULL, "file-offsets", "output file offsets, not text" }, { OP_NODATA, 'H', NULL, "with-filename", "force the prefixing filename on output" }, { OP_NODATA, 'h', NULL, "no-filename", "suppress the prefixing filename on output" }, { OP_NODATA, 'I', NULL, "", "treat binary files as not matching (ignore)" }, { OP_NODATA, 'i', NULL, "ignore-case", "ignore case distinctions" }, #ifdef SUPPORT_PCREGREP_JIT { OP_NODATA, N_NOJIT, NULL, "no-jit", "do not use just-in-time compiler optimization" }, #else { OP_NODATA, N_NOJIT, NULL, "no-jit", "ignored: this pcregrep does not support JIT" }, #endif { OP_NODATA, 'l', NULL, "files-with-matches", "print only FILE names containing matches" }, { OP_NODATA, 'L', NULL, "files-without-match","print only FILE names not containing matches" }, { OP_STRING, N_LABEL, &stdin_name, "label=name", "set name for standard input" }, { OP_NODATA, N_LBUFFER, NULL, "line-buffered", "use line buffering" }, { OP_NODATA, N_LOFFSETS, NULL, "line-offsets", "output line numbers and offsets, not text" }, { OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" }, { OP_LONGNUMBER, N_M_LIMIT, &match_limit, "match-limit=number", "set PCRE match limit option" }, { OP_LONGNUMBER, N_M_LIMIT_REC, &match_limit_recursion, "recursion-limit=number", "set PCRE match recursion limit option" }, { OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, { OP_STRING, 'N', &newline, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, { OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, { OP_OP_NUMBER, 'o', &only_matching, "only-matching=n", "show only the part of the line that matched" }, { OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" }, { OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" }, { OP_STRING, N_EXCLUDE,&exclude_pattern, "exclude=pattern","exclude matching files when recursing" }, { OP_STRING, N_INCLUDE,&include_pattern, "include=pattern","include matching files when recursing" }, { OP_STRING, N_EXCLUDE_DIR,&exclude_dir_pattern, "exclude-dir=pattern","exclude matching directories when recursing" }, { OP_STRING, N_INCLUDE_DIR,&include_dir_pattern, "include-dir=pattern","include matching directories when recursing" }, /* These two were accidentally implemented with underscores instead of hyphens in the option names. As this was not discovered for several releases, the incorrect versions are left in the table for compatibility. However, the --help function misses out any option that has an underscore in its name. */ { OP_STRING, N_EXCLUDE_DIR,&exclude_dir_pattern, "exclude_dir=pattern","exclude matching directories when recursing" }, { OP_STRING, N_INCLUDE_DIR,&include_dir_pattern, "include_dir=pattern","include matching directories when recursing" }, #ifdef JFRIEDL_DEBUG { OP_OP_NUMBER, 'S', &S_arg, "jeffS", "replace matched (sub)string with X" }, #endif { OP_NODATA, 's', NULL, "no-messages", "suppress error messages" }, { OP_NODATA, 'u', NULL, "utf-8", "use UTF-8 mode" }, { OP_NODATA, 'V', NULL, "version", "print version information and exit" }, { OP_NODATA, 'v', NULL, "invert-match", "select non-matching lines" }, { OP_NODATA, 'w', NULL, "word-regex(p)", "force patterns to match only as words" }, { OP_NODATA, 'x', NULL, "line-regex(p)", "force patterns to match only whole lines" }, { OP_NODATA, 0, NULL, NULL, NULL } }; /* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F options. These set the 1, 2, and 4 bits in process_options, respectively. Note that the combination of -w and -x has the same effect as -x on its own, so we can treat them as the same. */ static const char *prefix[] = { "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" }; static const char *suffix[] = { "", "\\b", ")$", ")$", "\\E", "\\E\\b", "\\E)$", "\\E)$" }; /* UTF-8 tables - used only when the newline setting is "any". */ const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; const char utf8_table4[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; /************************************************* * Exit from the program * *************************************************/ /* If there has been a resource error, give a suitable message. Argument: the return code Returns: does not return */ static void pcregrep_exit(int rc) { if (resource_error) { fprintf(stderr, "pcregrep: Error %d, %d or %d means that a resource limit " "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT, PCRE_ERROR_JIT_STACKLIMIT); fprintf(stderr, "pcregrep: Check your regex for nested unlimited loops.\n"); } exit(rc); } /************************************************* * OS-specific functions * *************************************************/ /* These functions are defined so that they can be made system specific, although at present the only ones are for Unix, Win32, and for "no support". */ /************* Directory scanning in Unix ***********/ #if defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H #include #include #include typedef DIR directory_type; static int isdirectory(char *filename) { struct stat statbuf; if (stat(filename, &statbuf) < 0) return 0; /* In the expectation that opening as a file will fail */ return ((statbuf.st_mode & S_IFMT) == S_IFDIR)? '/' : 0; } static directory_type * opendirectory(char *filename) { return opendir(filename); } static char * readdirectory(directory_type *dir) { for (;;) { struct dirent *dent = readdir(dir); if (dent == NULL) return NULL; if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) return dent->d_name; } /* Control never reaches here */ } static void closedirectory(directory_type *dir) { closedir(dir); } /************* Test for regular file in Unix **********/ static int isregfile(char *filename) { struct stat statbuf; if (stat(filename, &statbuf) < 0) return 1; /* In the expectation that opening as a file will fail */ return (statbuf.st_mode & S_IFMT) == S_IFREG; } /************* Test for a terminal in Unix **********/ static BOOL is_stdout_tty(void) { return isatty(fileno(stdout)); } static BOOL is_file_tty(FILE *f) { return isatty(fileno(f)); } /************* Directory scanning in Win32 ***********/ /* I (Philip Hazel) have no means of testing this code. It was contributed by Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES when it did not exist. David Byron added a patch that moved the #include of to before the INVALID_FILE_ATTRIBUTES definition rather than after. The double test below stops gcc 4.4.4 grumbling that HAVE_WINDOWS_H is undefined when it is indeed undefined. */ #elif defined HAVE_WINDOWS_H && HAVE_WINDOWS_H #ifndef STRICT # define STRICT #endif #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #include #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF #endif typedef struct directory_type { HANDLE handle; BOOL first; WIN32_FIND_DATA data; } directory_type; int isdirectory(char *filename) { DWORD attr = GetFileAttributes(filename); if (attr == INVALID_FILE_ATTRIBUTES) return 0; return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) ? '/' : 0; } directory_type * opendirectory(char *filename) { size_t len; char *pattern; directory_type *dir; DWORD err; len = strlen(filename); pattern = (char *) malloc(len + 3); dir = (directory_type *) malloc(sizeof(*dir)); if ((pattern == NULL) || (dir == NULL)) { fprintf(stderr, "pcregrep: malloc failed\n"); pcregrep_exit(2); } memcpy(pattern, filename, len); memcpy(&(pattern[len]), "\\*", 3); dir->handle = FindFirstFile(pattern, &(dir->data)); if (dir->handle != INVALID_HANDLE_VALUE) { free(pattern); dir->first = TRUE; return dir; } err = GetLastError(); free(pattern); free(dir); errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; return NULL; } char * readdirectory(directory_type *dir) { for (;;) { if (!dir->first) { if (!FindNextFile(dir->handle, &(dir->data))) return NULL; } else { dir->first = FALSE; } if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) return dir->data.cFileName; } #ifndef _MSC_VER return NULL; /* Keep compiler happy; never executed */ #endif } void closedirectory(directory_type *dir) { FindClose(dir->handle); free(dir); } /************* Test for regular file in Win32 **********/ /* I don't know how to do this, or if it can be done; assume all paths are regular if they are not directories. */ int isregfile(char *filename) { return !isdirectory(filename); } /************* Test for a terminal in Win32 **********/ /* I don't know how to do this; assume never */ static BOOL is_stdout_tty(void) { return FALSE; } static BOOL is_file_tty(FILE *f) { return FALSE; } /************* Directory scanning when we can't do it ***********/ /* The type is void, and apart from isdirectory(), the functions do nothing. */ #else typedef void directory_type; int isdirectory(char *filename) { return 0; } directory_type * opendirectory(char *filename) { return (directory_type*)0;} char *readdirectory(directory_type *dir) { return (char*)0;} void closedirectory(directory_type *dir) {} /************* Test for regular when we can't do it **********/ /* Assume all files are regular. */ int isregfile(char *filename) { return 1; } /************* Test for a terminal when we can't do it **********/ static BOOL is_stdout_tty(void) { return FALSE; } static BOOL is_file_tty(FILE *f) { return FALSE; } #endif #ifndef HAVE_STRERROR /************************************************* * Provide strerror() for non-ANSI libraries * *************************************************/ /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() in their libraries, but can provide the same facility by this simple alternative function. */ extern int sys_nerr; extern char *sys_errlist[]; char * strerror(int n) { if (n < 0 || n >= sys_nerr) return "unknown error number"; return sys_errlist[n]; } #endif /* HAVE_STRERROR */ /************************************************* * Read one line of input * *************************************************/ /* Normally, input is read using fread() into a large buffer, so many lines may be read at once. However, doing this for tty input means that no output appears until a lot of input has been typed. Instead, tty input is handled line by line. We cannot use fgets() for this, because it does not stop at a binary zero, and therefore there is no way of telling how many characters it has read, because there may be binary zeros embedded in the data. Arguments: buffer the buffer to read into length the maximum number of characters to read f the file Returns: the number of characters read, zero at end of file */ static unsigned int read_one_line(char *buffer, int length, FILE *f) { int c; int yield = 0; while ((c = fgetc(f)) != EOF) { buffer[yield++] = c; if (c == '\n' || yield >= length) break; } return yield; } /************************************************* * Find end of line * *************************************************/ /* The length of the endline sequence that is found is set via lenptr. This may be zero at the very end of the file if there is no line-ending sequence there. Arguments: p current position in line endptr end of available data lenptr where to put the length of the eol sequence Returns: pointer after the last byte of the line, including the newline byte(s) */ static char * end_of_line(char *p, char *endptr, int *lenptr) { switch(endlinetype) { default: /* Just in case */ case EL_LF: while (p < endptr && *p != '\n') p++; if (p < endptr) { *lenptr = 1; return p + 1; } *lenptr = 0; return endptr; case EL_CR: while (p < endptr && *p != '\r') p++; if (p < endptr) { *lenptr = 1; return p + 1; } *lenptr = 0; return endptr; case EL_CRLF: for (;;) { while (p < endptr && *p != '\r') p++; if (++p >= endptr) { *lenptr = 0; return endptr; } if (*p == '\n') { *lenptr = 2; return p + 1; } } break; case EL_ANYCRLF: while (p < endptr) { int extra = 0; register int c = *((unsigned char *)p); if (utf8 && c >= 0xc0) { int gcii, gcss; extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ gcss = 6*extra; c = (c & utf8_table3[extra]) << gcss; for (gcii = 1; gcii <= extra; gcii++) { gcss -= 6; c |= (p[gcii] & 0x3f) << gcss; } } p += 1 + extra; switch (c) { case 0x0a: /* LF */ *lenptr = 1; return p; case 0x0d: /* CR */ if (p < endptr && *p == 0x0a) { *lenptr = 2; p++; } else *lenptr = 1; return p; default: break; } } /* End of loop for ANYCRLF case */ *lenptr = 0; /* Must have hit the end */ return endptr; case EL_ANY: while (p < endptr) { int extra = 0; register int c = *((unsigned char *)p); if (utf8 && c >= 0xc0) { int gcii, gcss; extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ gcss = 6*extra; c = (c & utf8_table3[extra]) << gcss; for (gcii = 1; gcii <= extra; gcii++) { gcss -= 6; c |= (p[gcii] & 0x3f) << gcss; } } p += 1 + extra; switch (c) { case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ *lenptr = 1; return p; case 0x0d: /* CR */ if (p < endptr && *p == 0x0a) { *lenptr = 2; p++; } else *lenptr = 1; return p; case 0x85: /* NEL */ *lenptr = utf8? 2 : 1; return p; case 0x2028: /* LS */ case 0x2029: /* PS */ *lenptr = 3; return p; default: break; } } /* End of loop for ANY case */ *lenptr = 0; /* Must have hit the end */ return endptr; } /* End of overall switch */ } /************************************************* * Find start of previous line * *************************************************/ /* This is called when looking back for before lines to print. Arguments: p start of the subsequent line startptr start of available data Returns: pointer to the start of the previous line */ static char * previous_line(char *p, char *startptr) { switch(endlinetype) { default: /* Just in case */ case EL_LF: p--; while (p > startptr && p[-1] != '\n') p--; return p; case EL_CR: p--; while (p > startptr && p[-1] != '\n') p--; return p; case EL_CRLF: for (;;) { p -= 2; while (p > startptr && p[-1] != '\n') p--; if (p <= startptr + 1 || p[-2] == '\r') return p; } return p; /* But control should never get here */ case EL_ANY: case EL_ANYCRLF: if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--; if (utf8) while ((*p & 0xc0) == 0x80) p--; while (p > startptr) { register int c; char *pp = p - 1; if (utf8) { int extra = 0; while ((*pp & 0xc0) == 0x80) pp--; c = *((unsigned char *)pp); if (c >= 0xc0) { int gcii, gcss; extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ gcss = 6*extra; c = (c & utf8_table3[extra]) << gcss; for (gcii = 1; gcii <= extra; gcii++) { gcss -= 6; c |= (pp[gcii] & 0x3f) << gcss; } } } else c = *((unsigned char *)pp); if (endlinetype == EL_ANYCRLF) switch (c) { case 0x0a: /* LF */ case 0x0d: /* CR */ return p; default: break; } else switch (c) { case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LS */ case 0x2029: /* PS */ return p; default: break; } p = pp; /* Back one character */ } /* End of loop for ANY case */ return startptr; /* Hit start of data */ } /* End of overall switch */ } /************************************************* * Print the previous "after" lines * *************************************************/ /* This is called if we are about to lose said lines because of buffer filling, and at the end of the file. The data in the line is written using fwrite() so that a binary zero does not terminate it. Arguments: lastmatchnumber the number of the last matching line, plus one lastmatchrestart where we restarted after the last match endptr end of available data printname filename for printing Returns: nothing */ static void do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr, char *printname) { if (after_context > 0 && lastmatchnumber > 0) { int count = 0; while (lastmatchrestart < endptr && count++ < after_context) { int ellength; char *pp = lastmatchrestart; if (printname != NULL) fprintf(stdout, "%s-", printname); if (number) fprintf(stdout, "%d-", lastmatchnumber++); pp = end_of_line(pp, endptr, &ellength); FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); lastmatchrestart = pp; } hyphenpending = TRUE; } } /************************************************* * Apply patterns to subject till one matches * *************************************************/ /* This function is called to run through all patterns, looking for a match. It is used multiple times for the same subject when colouring is enabled, in order to find all possible matches. Arguments: matchptr the start of the subject length the length of the subject to match startoffset where to start matching offsets the offets vector to fill in mrc address of where to put the result of pcre_exec() Returns: TRUE if there was a match FALSE if there was no match invert if there was a non-fatal error */ static BOOL match_patterns(char *matchptr, size_t length, int startoffset, int *offsets, int *mrc) { int i; size_t slen = length; const char *msg = "this text:\n\n"; if (slen > 200) { slen = 200; msg = "text that starts:\n\n"; } for (i = 0; i < pattern_count; i++) { *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, (int)length, startoffset, PCRE_NOTEMPTY, offsets, OFFSET_SIZE); if (*mrc >= 0) return TRUE; if (*mrc == PCRE_ERROR_NOMATCH) continue; fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc); if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1); fprintf(stderr, "%s", msg); FWRITE(matchptr, 1, slen, stderr); /* In case binary zero included */ fprintf(stderr, "\n\n"); if (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT || *mrc == PCRE_ERROR_JIT_STACKLIMIT) resource_error = TRUE; if (error_count++ > 20) { fprintf(stderr, "pcregrep: Too many errors - abandoned.\n"); pcregrep_exit(2); } return invert; /* No more matching; don't show the line again */ } return FALSE; /* No match, no errors */ } /************************************************* * Grep an individual file * *************************************************/ /* This is called from grep_or_recurse() below. It uses a buffer that is three times the value of bufthird. The matching point is never allowed to stray into the top third of the buffer, thus keeping more of the file available for context printing or for multiline scanning. For large files, the pointer will be in the middle third most of the time, so the bottom third is available for "before" context printing. Arguments: handle the fopened FILE stream for a normal file the gzFile pointer when reading is via libz the BZFILE pointer when reading is via libbz2 frtype FR_PLAIN, FR_LIBZ, or FR_LIBBZ2 filename the file name or NULL (for errors) printname the file name if it is to be printed for each match or NULL if the file name is not to be printed it cannot be NULL if filenames[_nomatch]_only is set Returns: 0 if there was at least one match 1 otherwise (no matches) 2 if an overlong line is encountered 3 if there is a read error on a .bz2 file */ static int pcregrep(void *handle, int frtype, char *filename, char *printname) { int rc = 1; int linenumber = 1; int lastmatchnumber = 0; int count = 0; int filepos = 0; int offsets[OFFSET_SIZE]; char *lastmatchrestart = NULL; char *ptr = main_buffer; char *endptr; size_t bufflength; BOOL binary = FALSE; BOOL endhyphenpending = FALSE; BOOL input_line_buffered = line_buffered; FILE *in = NULL; /* Ensure initialized */ #ifdef SUPPORT_LIBZ gzFile ingz = NULL; #endif #ifdef SUPPORT_LIBBZ2 BZFILE *inbz2 = NULL; #endif /* Do the first read into the start of the buffer and set up the pointer to end of what we have. In the case of libz, a non-zipped .gz file will be read as a plain file. However, if a .bz2 file isn't actually bzipped, the first read will fail. */ #ifdef SUPPORT_LIBZ if (frtype == FR_LIBZ) { ingz = (gzFile)handle; bufflength = gzread (ingz, main_buffer, bufsize); } else #endif #ifdef SUPPORT_LIBBZ2 if (frtype == FR_LIBBZ2) { inbz2 = (BZFILE *)handle; bufflength = BZ2_bzread(inbz2, main_buffer, bufsize); if ((int)bufflength < 0) return 2; /* Gotcha: bufflength is size_t; */ } /* without the cast it is unsigned. */ else #endif { in = (FILE *)handle; if (is_file_tty(in)) input_line_buffered = TRUE; bufflength = input_line_buffered? read_one_line(main_buffer, bufsize, in) : fread(main_buffer, 1, bufsize, in); } endptr = main_buffer + bufflength; /* Unless binary-files=text, see if we have a binary file. This uses the same rule as GNU grep, namely, a search for a binary zero byte near the start of the file. */ if (binary_files != BIN_TEXT) { binary = memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL; if (binary && binary_files == BIN_NOMATCH) return 1; } /* Loop while the current pointer is not at the end of the file. For large files, endptr will be at the end of the buffer when we are in the middle of the file, but ptr will never get there, because as soon as it gets over 2/3 of the way, the buffer is shifted left and re-filled. */ while (ptr < endptr) { int endlinelength; int mrc = 0; int startoffset = 0; BOOL match; char *matchptr = ptr; char *t = ptr; size_t length, linelength; /* At this point, ptr is at the start of a line. We need to find the length of the subject string to pass to pcre_exec(). In multiline mode, it is the length remainder of the data in the buffer. Otherwise, it is the length of the next line, excluding the terminating newline. After matching, we always advance by the length of the next line. In multiline mode the PCRE_FIRSTLINE option is used for compiling, so that any match is constrained to be in the first line. */ t = end_of_line(t, endptr, &endlinelength); linelength = t - ptr - endlinelength; length = multiline? (size_t)(endptr - ptr) : linelength; /* Check to see if the line we are looking at extends right to the very end of the buffer without a line terminator. This means the line is too long to handle. */ if (endlinelength == 0 && t == main_buffer + bufsize) { fprintf(stderr, "pcregrep: line %d%s%s is too long for the internal buffer\n" "pcregrep: check the --buffer-size option\n", linenumber, (filename == NULL)? "" : " of file ", (filename == NULL)? "" : filename); return 2; } /* Extra processing for Jeffrey Friedl's debugging. */ #ifdef JFRIEDL_DEBUG if (jfriedl_XT || jfriedl_XR) { #include #include struct timeval start_time, end_time; struct timezone dummy; int i; if (jfriedl_XT) { unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix); const char *orig = ptr; ptr = malloc(newlen + 1); if (!ptr) { printf("out of memory"); pcregrep_exit(2); } endptr = ptr; strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix); for (i = 0; i < jfriedl_XT; i++) { strncpy(endptr, orig, length); endptr += length; } strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix); length = newlen; } if (gettimeofday(&start_time, &dummy) != 0) perror("bad gettimeofday"); for (i = 0; i < jfriedl_XR; i++) match = (pcre_exec(pattern_list[0], hints_list[0], ptr, length, 0, PCRE_NOTEMPTY, offsets, OFFSET_SIZE) >= 0); if (gettimeofday(&end_time, &dummy) != 0) perror("bad gettimeofday"); double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0)) - (start_time.tv_sec + (start_time.tv_usec / 1000000.0))); printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta); return 0; } #endif /* We come back here after a match when the -o option (only_matching) is set, in order to find any further matches in the same line. */ ONLY_MATCHING_RESTART: /* Run through all the patterns until one matches or there is an error other than NOMATCH. This code is in a subroutine so that it can be re-used for finding subsequent matches when colouring matched lines. */ match = match_patterns(matchptr, length, startoffset, offsets, &mrc); /* If it's a match or a not-match (as required), do what's wanted. */ if (match != invert) { BOOL hyphenprinted = FALSE; /* We've failed if we want a file that doesn't have any matches. */ if (filenames == FN_NOMATCH_ONLY) return 1; /* Just count if just counting is wanted. */ if (count_only) count++; /* When handling a binary file and binary-files==binary, the "binary" variable will be set true (it's false in all other cases). In this situation we just want to output the file name. No need to scan further. */ else if (binary) { fprintf(stdout, "Binary file %s matches\n", filename); return 0; } /* If all we want is a file name, there is no need to scan any more lines in the file. */ else if (filenames == FN_MATCH_ONLY) { fprintf(stdout, "%s\n", printname); return 0; } /* Likewise, if all we want is a yes/no answer. */ else if (quiet) return 0; /* The --only-matching option prints just the substring that matched, or a captured portion of it, as long as this string is not empty, and the --file-offsets and --line-offsets options output offsets for the matching substring (they both force --only-matching = 0). None of these options prints any context. Afterwards, adjust the start and then jump back to look for further matches in the same line. If we are in invert mode, however, nothing is printed and we do not restart - this could still be useful because the return code is set. */ else if (only_matching >= 0) { if (!invert) { if (printname != NULL) fprintf(stdout, "%s:", printname); if (number) fprintf(stdout, "%d:", linenumber); if (line_offsets) fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr), offsets[1] - offsets[0]); else if (file_offsets) fprintf(stdout, "%d,%d\n", (int)(filepos + matchptr + offsets[0] - ptr), offsets[1] - offsets[0]); else if (only_matching < mrc) { int plen = offsets[2*only_matching + 1] - offsets[2*only_matching]; if (plen > 0) { if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string); FWRITE(matchptr + offsets[only_matching*2], 1, plen, stdout); if (do_colour) fprintf(stdout, "%c[00m", 0x1b); fprintf(stdout, "\n"); } } else if (printname != NULL || number) fprintf(stdout, "\n"); match = FALSE; if (line_buffered) fflush(stdout); rc = 0; /* Had some success */ startoffset = offsets[1]; /* Restart after the match */ goto ONLY_MATCHING_RESTART; } } /* This is the default case when none of the above options is set. We print the matching lines(s), possibly preceded and/or followed by other lines of context. */ else { /* See if there is a requirement to print some "after" lines from a previous match. We never print any overlaps. */ if (after_context > 0 && lastmatchnumber > 0) { int ellength; int linecount = 0; char *p = lastmatchrestart; while (p < ptr && linecount < after_context) { p = end_of_line(p, ptr, &ellength); linecount++; } /* It is important to advance lastmatchrestart during this printing so that it interacts correctly with any "before" printing below. Print each line's data using fwrite() in case there are binary zeroes. */ while (lastmatchrestart < p) { char *pp = lastmatchrestart; if (printname != NULL) fprintf(stdout, "%s-", printname); if (number) fprintf(stdout, "%d-", lastmatchnumber++); pp = end_of_line(pp, endptr, &ellength); FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); lastmatchrestart = pp; } if (lastmatchrestart != ptr) hyphenpending = TRUE; } /* If there were non-contiguous lines printed above, insert hyphens. */ if (hyphenpending) { fprintf(stdout, "--\n"); hyphenpending = FALSE; hyphenprinted = TRUE; } /* See if there is a requirement to print some "before" lines for this match. Again, don't print overlaps. */ if (before_context > 0) { int linecount = 0; char *p = ptr; while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) && linecount < before_context) { linecount++; p = previous_line(p, main_buffer); } if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted) fprintf(stdout, "--\n"); while (p < ptr) { int ellength; char *pp = p; if (printname != NULL) fprintf(stdout, "%s-", printname); if (number) fprintf(stdout, "%d-", linenumber - linecount--); pp = end_of_line(pp, endptr, &ellength); FWRITE(p, 1, pp - p, stdout); p = pp; } } /* Now print the matching line(s); ensure we set hyphenpending at the end of the file if any context lines are being output. */ if (after_context > 0 || before_context > 0) endhyphenpending = TRUE; if (printname != NULL) fprintf(stdout, "%s:", printname); if (number) fprintf(stdout, "%d:", linenumber); /* 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, but only when there actually was a match (invert not set). Because the PCRE_FIRSTLINE option is set, the start of the match will always be before the first newline sequence. */ if (multiline & !invert) { char *endmatch = ptr + offsets[1]; t = ptr; while (t < endmatch) { t = end_of_line(t, endptr, &endlinelength); if (t < endmatch) linenumber++; else break; } linelength = t - ptr - endlinelength; } /*** NOTE: Use only fwrite() to output the data line, so that binary zeroes are treated as just another data character. */ /* This extra option, for Jeffrey Friedl's debugging requirements, replaces the matched string, or a specific captured string if it exists, with X. When this happens, colouring is ignored. */ #ifdef JFRIEDL_DEBUG if (S_arg >= 0 && S_arg < mrc) { int first = S_arg * 2; int last = first + 1; FWRITE(ptr, 1, offsets[first], stdout); fprintf(stdout, "X"); FWRITE(ptr + offsets[last], 1, linelength - offsets[last], stdout); } else #endif /* We have to split the line(s) up if colouring, and search for further matches, but not of course if the line is a non-match. */ if (do_colour && !invert) { int plength; FWRITE(ptr, 1, offsets[0], stdout); fprintf(stdout, "%c[%sm", 0x1b, colour_string); FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout); fprintf(stdout, "%c[00m", 0x1b); for (;;) { startoffset = offsets[1]; if (startoffset >= (int)linelength + endlinelength || !match_patterns(matchptr, length, startoffset, offsets, &mrc)) break; FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout); fprintf(stdout, "%c[%sm", 0x1b, colour_string); FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout); fprintf(stdout, "%c[00m", 0x1b); } /* In multiline mode, we may have already printed the complete line and its line-ending characters (if they matched the pattern), so there may be no more to print. */ plength = (int)((linelength + endlinelength) - startoffset); if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout); } /* Not colouring; no need to search for further matches */ else FWRITE(ptr, 1, linelength + endlinelength, stdout); } /* End of doing what has to be done for a match. If --line-buffered was given, flush the output. */ if (line_buffered) fflush(stdout); rc = 0; /* Had some success */ /* Remember where the last match happened for after_context. We remember where we are about to restart, and that line's number. */ lastmatchrestart = ptr + linelength + endlinelength; lastmatchnumber = linenumber + 1; } /* For a match in multiline inverted mode (which of course did not cause anything to be printed), we have to move on to the end of the match before proceeding. */ if (multiline && invert && match) { int ellength; char *endmatch = ptr + offsets[1]; t = ptr; while (t < endmatch) { t = end_of_line(t, endptr, &ellength); if (t <= endmatch) linenumber++; else break; } endmatch = end_of_line(endmatch, endptr, &ellength); linelength = endmatch - ptr - ellength; } /* Advance to after the newline and increment the line number. The file offset to the current line is maintained in filepos. */ ptr += linelength + endlinelength; filepos += (int)(linelength + endlinelength); linenumber++; /* If input is line buffered, and the buffer is not yet full, read another line and add it into the buffer. */ if (input_line_buffered && bufflength < (size_t)bufsize) { int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in); bufflength += add; endptr += add; } /* If we haven't yet reached the end of the file (the buffer is full), and the current point is in the top 1/3 of the buffer, slide the buffer down by 1/3 and refill it. Before we do this, if some unprinted "after" lines are about to be lost, print them. */ if (bufflength >= (size_t)bufsize && ptr > main_buffer + 2*bufthird) { if (after_context > 0 && lastmatchnumber > 0 && lastmatchrestart < main_buffer + bufthird) { do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); lastmatchnumber = 0; } /* Now do the shuffle */ memmove(main_buffer, main_buffer + bufthird, 2*bufthird); ptr -= bufthird; #ifdef SUPPORT_LIBZ if (frtype == FR_LIBZ) bufflength = 2*bufthird + gzread (ingz, main_buffer + 2*bufthird, bufthird); else #endif #ifdef SUPPORT_LIBBZ2 if (frtype == FR_LIBBZ2) bufflength = 2*bufthird + BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird); else #endif bufflength = 2*bufthird + (input_line_buffered? read_one_line(main_buffer + 2*bufthird, bufthird, in) : fread(main_buffer + 2*bufthird, 1, bufthird, in)); endptr = main_buffer + bufflength; /* Adjust any last match point */ if (lastmatchnumber > 0) lastmatchrestart -= bufthird; } } /* Loop through the whole file */ /* End of file; print final "after" lines if wanted; do_after_lines sets hyphenpending if it prints something. */ if (only_matching < 0 && !count_only) { do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); hyphenpending |= endhyphenpending; } /* Print the file name if we are looking for those without matches and there were none. If we found a match, we won't have got this far. */ if (filenames == FN_NOMATCH_ONLY) { fprintf(stdout, "%s\n", printname); return 0; } /* Print the match count if wanted */ if (count_only) { if (count > 0 || !omit_zero_count) { if (printname != NULL && filenames != FN_NONE) fprintf(stdout, "%s:", printname); fprintf(stdout, "%d\n", count); } } return rc; } /************************************************* * Grep a file or recurse into a directory * *************************************************/ /* Given a path name, if it's a directory, scan all the files if we are recursing; if it's a file, grep it. Arguments: pathname the path to investigate dir_recurse TRUE if recursing is wanted (-r or -drecurse) only_one_at_top TRUE if the path is the only one at toplevel Returns: 0 if there was at least one match 1 if there were no matches 2 there was some kind of error However, file opening failures are suppressed if "silent" is set. */ static int grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top) { int rc = 1; int sep; int frtype; void *handle; FILE *in = NULL; /* Ensure initialized */ #ifdef SUPPORT_LIBZ gzFile ingz = NULL; #endif #ifdef SUPPORT_LIBBZ2 BZFILE *inbz2 = NULL; #endif #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 int pathlen; #endif /* If the file name is "-" we scan stdin */ if (strcmp(pathname, "-") == 0) { return pcregrep(stdin, FR_PLAIN, stdin_name, (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? stdin_name : NULL); } /* If the file is a directory, skip if skipping or if we are recursing, scan each file and directory within it, subject to any include or exclude patterns that were set. The scanning code is localized so it can be made system-specific. */ if ((sep = isdirectory(pathname)) != 0) { if (dee_action == dee_SKIP) return 1; if (dee_action == dee_RECURSE) { char buffer[1024]; char *nextfile; directory_type *dir = opendirectory(pathname); if (dir == NULL) { if (!silent) fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", pathname, strerror(errno)); return 2; } while ((nextfile = readdirectory(dir)) != NULL) { int frc, nflen; sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile); nflen = (int)(strlen(nextfile)); if (isdirectory(buffer)) { if (exclude_dir_compiled != NULL && pcre_exec(exclude_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0) continue; if (include_dir_compiled != NULL && pcre_exec(include_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0) continue; } else { if (exclude_compiled != NULL && pcre_exec(exclude_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0) continue; if (include_compiled != NULL && pcre_exec(include_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0) continue; } frc = grep_or_recurse(buffer, dir_recurse, FALSE); if (frc > 1) rc = frc; else if (frc == 0 && rc == 1) rc = 0; } closedirectory(dir); return rc; } } /* If the file is not a directory and not a regular file, skip it if that's been requested. */ else if (!isregfile(pathname) && DEE_action == DEE_SKIP) return 1; /* Control reaches here if we have a regular file, or if we have a directory and recursion or skipping was not requested, or if we have anything else and skipping was not requested. The scan proceeds. If this is the first and only argument at top level, we don't show the file name, unless we are only showing the file name, or the filename was forced (-H). */ #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 pathlen = (int)(strlen(pathname)); #endif /* Open using zlib if it is supported and the file name ends with .gz. */ #ifdef SUPPORT_LIBZ if (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0) { ingz = gzopen(pathname, "rb"); if (ingz == NULL) { if (!silent) fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname, strerror(errno)); return 2; } handle = (void *)ingz; frtype = FR_LIBZ; } else #endif /* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */ #ifdef SUPPORT_LIBBZ2 if (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0) { inbz2 = BZ2_bzopen(pathname, "rb"); handle = (void *)inbz2; frtype = FR_LIBBZ2; } else #endif /* Otherwise use plain fopen(). The label is so that we can come back here if an attempt to read a .bz2 file indicates that it really is a plain file. */ #ifdef SUPPORT_LIBBZ2 PLAIN_FILE: #endif { in = fopen(pathname, "rb"); handle = (void *)in; frtype = FR_PLAIN; } /* All the opening methods return errno when they fail. */ if (handle == NULL) { if (!silent) fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname, strerror(errno)); return 2; } /* Now grep the file */ rc = pcregrep(handle, frtype, pathname, (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL); /* Close in an appropriate manner. */ #ifdef SUPPORT_LIBZ if (frtype == FR_LIBZ) gzclose(ingz); else #endif /* If it is a .bz2 file and the result is 3, it means that the first attempt to read failed. If the error indicates that the file isn't in fact bzipped, try again as a normal file. */ #ifdef SUPPORT_LIBBZ2 if (frtype == FR_LIBBZ2) { if (rc == 3) { int errnum; const char *err = BZ2_bzerror(inbz2, &errnum); if (errnum == BZ_DATA_ERROR_MAGIC) { BZ2_bzclose(inbz2); goto PLAIN_FILE; } else if (!silent) fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n", pathname, err); rc = 2; /* The normal "something went wrong" code */ } BZ2_bzclose(inbz2); } else #endif /* Normal file close */ fclose(in); /* Pass back the yield from pcregrep(). */ return rc; } /************************************************* * Usage function * *************************************************/ static int usage(int rc) { option_item *op; fprintf(stderr, "Usage: pcregrep [-"); for (op = optionlist; op->one_char != 0; op++) { if (op->one_char > 0) fprintf(stderr, "%c", op->one_char); } fprintf(stderr, "] [long options] [pattern] [files]\n"); fprintf(stderr, "Type `pcregrep --help' for more information and the long " "options.\n"); return rc; } /************************************************* * Help function * *************************************************/ static void help(void) { option_item *op; printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); printf("Search for PATTERN in each FILE or standard input.\n"); printf("PATTERN must be present if neither -e nor -f is used.\n"); printf("\"-\" can be used as a file name to mean STDIN.\n"); #ifdef SUPPORT_LIBZ printf("Files whose names end in .gz are read using zlib.\n"); #endif #ifdef SUPPORT_LIBBZ2 printf("Files whose names end in .bz2 are read using bzlib2.\n"); #endif #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 printf("Other files and the standard input are read as plain files.\n\n"); #else printf("All files are read as plain files, without any interpretation.\n\n"); #endif printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n"); printf("Options:\n"); for (op = optionlist; op->one_char != 0; op++) { int n; char s[4]; /* Two options were accidentally implemented and documented with underscores instead of hyphens in their names, something that was not noticed for quite a few releases. When fixing this, I left the underscored versions in the list in case people were using them. However, we don't want to display them in the help data. There are no other options that contain underscores, and we do not expect ever to implement such options. Therefore, just omit any option that contains an underscore. */ if (strchr(op->long_name, '_') != NULL) continue; if (op->one_char > 0 && (op->long_name)[0] == 0) n = 31 - printf(" -%c", op->one_char); else { if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, " "); n = 31 - printf(" %s --%s", s, op->long_name); } if (n < 1) n = 1; printf("%.*s%s\n", n, " ", op->help_text); } printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n"); printf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE); printf("When reading patterns or file names from a file, trailing white\n"); printf("space is removed and blank lines are ignored.\n"); printf("There is a maximum of %d patterns, each of maximum size %d bytes.\n", MAX_PATTERN_COUNT, PATBUFSIZE); printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n"); printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); } /************************************************* * Handle a single-letter, no data option * *************************************************/ static int handle_option(int letter, int options) { switch(letter) { case N_FOFFSETS: file_offsets = TRUE; break; case N_HELP: help(); pcregrep_exit(0); case N_LBUFFER: line_buffered = TRUE; break; case N_LOFFSETS: line_offsets = number = TRUE; break; case N_NOJIT: study_options &= ~PCRE_STUDY_JIT_COMPILE; break; case 'a': binary_files = BIN_TEXT; break; case 'c': count_only = TRUE; break; case 'F': process_options |= PO_FIXED_STRINGS; break; case 'H': filenames = FN_FORCE; break; case 'I': binary_files = BIN_NOMATCH; break; case 'h': filenames = FN_NONE; break; case 'i': options |= PCRE_CASELESS; break; case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break; case 'L': filenames = FN_NOMATCH_ONLY; break; case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break; case 'n': number = TRUE; break; case 'o': only_matching = 0; break; case 'q': quiet = TRUE; break; case 'r': dee_action = dee_RECURSE; break; case 's': silent = TRUE; break; case 'u': options |= PCRE_UTF8; utf8 = TRUE; break; case 'v': invert = TRUE; break; case 'w': process_options |= PO_WORD_MATCH; break; case 'x': process_options |= PO_LINE_MATCH; break; case 'V': fprintf(stderr, "pcregrep version %s\n", pcre_version()); pcregrep_exit(0); break; default: fprintf(stderr, "pcregrep: Unknown option -%c\n", letter); pcregrep_exit(usage(2)); } return options; } /************************************************* * Construct printed ordinal * *************************************************/ /* This turns a number into "1st", "3rd", etc. */ static char * ordin(int n) { static char buffer[8]; char *p = buffer; sprintf(p, "%d", n); while (*p != 0) p++; switch (n%10) { case 1: strcpy(p, "st"); break; case 2: strcpy(p, "nd"); break; case 3: strcpy(p, "rd"); break; default: strcpy(p, "th"); break; } return buffer; } /************************************************* * Compile a single pattern * *************************************************/ /* When the -F option has been used, this is called for each substring. Otherwise it's called for each supplied pattern. Arguments: pattern the pattern string options the PCRE options filename the file name, or NULL for a command-line pattern count 0 if this is the only command line pattern, or number of the command line pattern, or linenumber for a pattern from a file Returns: TRUE on success, FALSE after an error */ static BOOL compile_single_pattern(char *pattern, int options, char *filename, int count) { char buffer[PATBUFSIZE]; const char *error; int errptr; if (pattern_count >= MAX_PATTERN_COUNT) { fprintf(stderr, "pcregrep: Too many %spatterns (max %d)\n", (filename == NULL)? "command-line " : "", MAX_PATTERN_COUNT); return FALSE; } sprintf(buffer, "%s%.*s%s", prefix[process_options], bufthird, pattern, suffix[process_options]); pattern_list[pattern_count] = pcre_compile(buffer, options, &error, &errptr, pcretables); if (pattern_list[pattern_count] != NULL) { pattern_count++; return TRUE; } /* Handle compile errors */ errptr -= (int)strlen(prefix[process_options]); if (errptr > (int)strlen(pattern)) errptr = (int)strlen(pattern); if (filename == NULL) { if (count == 0) fprintf(stderr, "pcregrep: Error in command-line regex " "at offset %d: %s\n", errptr, error); else fprintf(stderr, "pcregrep: Error in %s command-line regex " "at offset %d: %s\n", ordin(count), errptr, error); } else { fprintf(stderr, "pcregrep: Error in regex in line %d of %s " "at offset %d: %s\n", count, filename, errptr, error); } return FALSE; } /************************************************* * Compile one supplied pattern * *************************************************/ /* When the -F option has been used, each string may be a list of strings, separated by line breaks. They will be matched literally. Arguments: pattern the pattern string options the PCRE options filename the file name, or NULL for a command-line pattern count 0 if this is the only command line pattern, or number of the command line pattern, or linenumber for a pattern from a file Returns: TRUE on success, FALSE after an error */ static BOOL compile_pattern(char *pattern, int options, char *filename, int count) { if ((process_options & PO_FIXED_STRINGS) != 0) { char *eop = pattern + strlen(pattern); char buffer[PATBUFSIZE]; for(;;) { int ellength; char *p = end_of_line(pattern, eop, &ellength); if (ellength == 0) return compile_single_pattern(pattern, options, filename, count); sprintf(buffer, "%.*s", (int)(p - pattern - ellength), pattern); pattern = p; if (!compile_single_pattern(buffer, options, filename, count)) return FALSE; } } else return compile_single_pattern(pattern, options, filename, count); } /************************************************* * Main program * *************************************************/ /* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */ int main(int argc, char **argv) { int i, j; int rc = 1; int pcre_options = 0; int cmd_pattern_count = 0; int hint_count = 0; int errptr; BOOL only_one_at_top; char *patterns[MAX_PATTERN_COUNT]; const char *locale_from = "--locale"; const char *error; #ifdef SUPPORT_PCREGREP_JIT pcre_jit_stack *jit_stack = NULL; #endif /* Set the default line ending value from the default in the PCRE library; "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf". Note that the return values from pcre_config(), though derived from the ASCII codes, are the same in EBCDIC environments, so we must use the actual values rather than escapes such as as '\r'. */ (void)pcre_config(PCRE_CONFIG_NEWLINE, &i); switch(i) { default: newline = (char *)"lf"; break; case 13: newline = (char *)"cr"; break; case (13 << 8) | 10: newline = (char *)"crlf"; break; case -1: newline = (char *)"any"; break; case -2: newline = (char *)"anycrlf"; break; } /* Process the options */ for (i = 1; i < argc; i++) { option_item *op = NULL; char *option_data = (char *)""; /* default to keep compiler happy */ BOOL longop; BOOL longopwasequals = FALSE; if (argv[i][0] != '-') break; /* If we hit an argument that is just "-", it may be a reference to STDIN, but only if we have previously had -e or -f to define the patterns. */ if (argv[i][1] == 0) { if (pattern_filename != NULL || pattern_count > 0) break; else pcregrep_exit(usage(2)); } /* Handle a long name option, or -- to terminate the options */ if (argv[i][1] == '-') { char *arg = argv[i] + 2; char *argequals = strchr(arg, '='); if (*arg == 0) /* -- terminates options */ { i++; break; /* out of the options-handling loop */ } longop = TRUE; /* Some long options have data that follows after =, for example file=name. Some options have variations in the long name spelling: specifically, we allow "regexp" because GNU grep allows it, though I personally go along with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p". These options are entered in the table as "regex(p)". Options can be in both these categories. */ for (op = optionlist; op->one_char != 0; op++) { char *opbra = strchr(op->long_name, '('); char *equals = strchr(op->long_name, '='); /* Handle options with only one spelling of the name */ if (opbra == NULL) /* Does not contain '(' */ { if (equals == NULL) /* Not thing=data case */ { if (strcmp(arg, op->long_name) == 0) break; } else /* Special case xxx=data */ { int oplen = (int)(equals - op->long_name); int arglen = (argequals == NULL)? (int)strlen(arg) : (int)(argequals - arg); if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0) { option_data = arg + arglen; if (*option_data == '=') { option_data++; longopwasequals = TRUE; } break; } } } /* Handle options with an alternate spelling of the name */ else { char buff1[24]; char buff2[24]; int baselen = (int)(opbra - op->long_name); int fulllen = (int)(strchr(op->long_name, ')') - op->long_name + 1); int arglen = (argequals == NULL || equals == NULL)? (int)strlen(arg) : (int)(argequals - arg); sprintf(buff1, "%.*s", baselen, op->long_name); sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1); if (strncmp(arg, buff1, arglen) == 0 || strncmp(arg, buff2, arglen) == 0) { if (equals != NULL && argequals != NULL) { option_data = argequals; if (*option_data == '=') { option_data++; longopwasequals = TRUE; } } break; } } } if (op->one_char == 0) { fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]); pcregrep_exit(usage(2)); } } /* Jeffrey Friedl's debugging harness uses these additional options which are not in the right form for putting in the option table because they use only one hyphen, yet are more than one character long. By putting them separately here, they will not get displayed as part of the help() output, but I don't think Jeffrey will care about that. */ #ifdef JFRIEDL_DEBUG else if (strcmp(argv[i], "-pre") == 0) { jfriedl_prefix = argv[++i]; continue; } else if (strcmp(argv[i], "-post") == 0) { jfriedl_postfix = argv[++i]; continue; } else if (strcmp(argv[i], "-XT") == 0) { sscanf(argv[++i], "%d", &jfriedl_XT); continue; } else if (strcmp(argv[i], "-XR") == 0) { sscanf(argv[++i], "%d", &jfriedl_XR); continue; } #endif /* One-char options; many that have no data may be in a single argument; we continue till we hit the last one or one that needs data. */ else { char *s = argv[i] + 1; longop = FALSE; while (*s != 0) { for (op = optionlist; op->one_char != 0; op++) { if (*s == op->one_char) break; } if (op->one_char == 0) { fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n", *s, argv[i]); pcregrep_exit(usage(2)); } /* Check for a single-character option that has data: OP_OP_NUMBER is used for one that either has a numerical number or defaults, i.e. the data is optional. If a digit follows, there is data; if not, carry on with other single-character options in the same string. */ option_data = s+1; if (op->type == OP_OP_NUMBER) { if (isdigit((unsigned char)s[1])) break; } else /* Check for end or a dataless option */ { if (op->type != OP_NODATA || s[1] == 0) break; } /* Handle a single-character option with no data, then loop for the next character in the string. */ pcre_options = handle_option(*s++, pcre_options); } } /* At this point we should have op pointing to a matched option. If the type is NO_DATA, it means that there is no data, and the option might set something in the PCRE options. */ if (op->type == OP_NODATA) { pcre_options = handle_option(op->one_char, pcre_options); continue; } /* If the option type is OP_OP_STRING or OP_OP_NUMBER, it's an option that either has a value or defaults to something. It cannot have data in a separate item. At the moment, the only such options are "colo(u)r", "only-matching", and Jeffrey Friedl's special -S debugging option. */ if (*option_data == 0 && (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER)) { switch (op->one_char) { case N_COLOUR: colour_option = (char *)"auto"; break; case 'o': only_matching = 0; break; #ifdef JFRIEDL_DEBUG case 'S': S_arg = 0; break; #endif } continue; } /* Otherwise, find the data string for the option. */ if (*option_data == 0) { if (i >= argc - 1 || longopwasequals) { fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]); pcregrep_exit(usage(2)); } option_data = argv[++i]; } /* If the option type is OP_PATLIST, it's the -e option, which can be called multiple times to create a list of patterns. */ if (op->type == OP_PATLIST) { if (cmd_pattern_count >= MAX_PATTERN_COUNT) { fprintf(stderr, "pcregrep: Too many command-line patterns (max %d)\n", MAX_PATTERN_COUNT); return 2; } patterns[cmd_pattern_count++] = option_data; } /* Handle OP_BINARY_FILES */ else if (op->type == OP_BINFILES) { if (strcmp(option_data, "binary") == 0) binary_files = BIN_BINARY; else if (strcmp(option_data, "without-match") == 0) binary_files = BIN_NOMATCH; else if (strcmp(option_data, "text") == 0) binary_files = BIN_TEXT; else { fprintf(stderr, "pcregrep: unknown value \"%s\" for binary-files\n", option_data); pcregrep_exit(usage(2)); } } /* Otherwise, deal with single string or numeric data values. */ else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER && op->type != OP_OP_NUMBER) { *((char **)op->dataptr) = option_data; } /* Avoid the use of strtoul() because SunOS4 doesn't have it. This is used only for unpicking arguments, so just keep it simple. */ else { unsigned long int n = 0; char *endptr = option_data; while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++; while (isdigit((unsigned char)(*endptr))) n = n * 10 + (int)(*endptr++ - '0'); if (toupper(*endptr) == 'K') { n *= 1024; endptr++; } else if (toupper(*endptr) == 'M') { n *= 1024*1024; endptr++; } if (*endptr != 0) { if (longop) { char *equals = strchr(op->long_name, '='); int nlen = (equals == NULL)? (int)strlen(op->long_name) : (int)(equals - op->long_name); fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%.*s\n", option_data, nlen, op->long_name); } else fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n", option_data, op->one_char); pcregrep_exit(usage(2)); } if (op->type == OP_LONGNUMBER) *((unsigned long int *)op->dataptr) = n; else *((int *)op->dataptr) = n; } } /* Options have been decoded. If -C was used, its value is used as a default for -A and -B. */ if (both_context > 0) { if (after_context == 0) after_context = both_context; if (before_context == 0) before_context = both_context; } /* Only one of --only-matching, --file-offsets, or --line-offsets is permitted. However, the latter two set only_matching. */ if ((only_matching >= 0 && (file_offsets || line_offsets)) || (file_offsets && line_offsets)) { fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets " "and/or --line-offsets\n"); pcregrep_exit(usage(2)); } if (file_offsets || line_offsets) only_matching = 0; /* If a locale has not been provided as an option, see if the LC_CTYPE or LC_ALL environment variable is set, and if so, use it. */ if (locale == NULL) { locale = getenv("LC_ALL"); locale_from = "LCC_ALL"; } if (locale == NULL) { locale = getenv("LC_CTYPE"); locale_from = "LC_CTYPE"; } /* If a locale has been provided, set it, and generate the tables the PCRE needs. Otherwise, pcretables==NULL, which causes the use of default tables. */ if (locale != NULL) { if (setlocale(LC_CTYPE, locale) == NULL) { fprintf(stderr, "pcregrep: Failed to set locale %s (obtained from %s)\n", locale, locale_from); return 2; } pcretables = pcre_maketables(); } /* Sort out colouring */ if (colour_option != NULL && strcmp(colour_option, "never") != 0) { if (strcmp(colour_option, "always") == 0) do_colour = TRUE; else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty(); else { fprintf(stderr, "pcregrep: Unknown colour setting \"%s\"\n", colour_option); return 2; } if (do_colour) { char *cs = getenv("PCREGREP_COLOUR"); if (cs == NULL) cs = getenv("PCREGREP_COLOR"); if (cs != NULL) colour_string = cs; } } /* Interpret the newline type; the default settings are Unix-like. */ if (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0) { pcre_options |= PCRE_NEWLINE_CR; endlinetype = EL_CR; } else if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0) { pcre_options |= PCRE_NEWLINE_LF; endlinetype = EL_LF; } else if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0) { pcre_options |= PCRE_NEWLINE_CRLF; endlinetype = EL_CRLF; } else if (strcmp(newline, "any") == 0 || strcmp(newline, "ANY") == 0) { pcre_options |= PCRE_NEWLINE_ANY; endlinetype = EL_ANY; } else if (strcmp(newline, "anycrlf") == 0 || strcmp(newline, "ANYCRLF") == 0) { pcre_options |= PCRE_NEWLINE_ANYCRLF; endlinetype = EL_ANYCRLF; } else { fprintf(stderr, "pcregrep: Invalid newline specifier \"%s\"\n", newline); return 2; } /* Interpret the text values for -d and -D */ if (dee_option != NULL) { if (strcmp(dee_option, "read") == 0) dee_action = dee_READ; else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE; else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP; else { fprintf(stderr, "pcregrep: Invalid value \"%s\" for -d\n", dee_option); return 2; } } if (DEE_option != NULL) { if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ; else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP; else { fprintf(stderr, "pcregrep: Invalid value \"%s\" for -D\n", DEE_option); return 2; } } /* Check the values for Jeffrey Friedl's debugging options. */ #ifdef JFRIEDL_DEBUG if (S_arg > 9) { fprintf(stderr, "pcregrep: bad value for -S option\n"); return 2; } if (jfriedl_XT != 0 || jfriedl_XR != 0) { if (jfriedl_XT == 0) jfriedl_XT = 1; if (jfriedl_XR == 0) jfriedl_XR = 1; } #endif /* Get memory for the main buffer, and to store the pattern and hints lists. */ bufsize = 3*bufthird; main_buffer = (char *)malloc(bufsize); pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *)); hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *)); if (main_buffer == NULL || pattern_list == NULL || hints_list == NULL) { fprintf(stderr, "pcregrep: malloc failed\n"); goto EXIT2; } /* If no patterns were provided by -e, and there is no file provided by -f, the first argument is the one and only pattern, and it must exist. */ if (cmd_pattern_count == 0 && pattern_filename == NULL) { if (i >= argc) return usage(2); patterns[cmd_pattern_count++] = argv[i++]; } /* Compile the patterns that were provided on the command line, either by multiple uses of -e or as a single unkeyed pattern. */ for (j = 0; j < cmd_pattern_count; j++) { if (!compile_pattern(patterns[j], pcre_options, NULL, (j == 0 && cmd_pattern_count == 1)? 0 : j + 1)) goto EXIT2; } /* Compile the regular expressions that are provided in a file. */ if (pattern_filename != NULL) { int linenumber = 0; FILE *f; char *filename; char buffer[PATBUFSIZE]; if (strcmp(pattern_filename, "-") == 0) { f = stdin; filename = stdin_name; } else { f = fopen(pattern_filename, "r"); if (f == NULL) { fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename, strerror(errno)); goto EXIT2; } filename = pattern_filename; } while (fgets(buffer, PATBUFSIZE, f) != NULL) { char *s = buffer + (int)strlen(buffer); while (s > buffer && isspace((unsigned char)(s[-1]))) s--; *s = 0; linenumber++; if (buffer[0] == 0) continue; /* Skip blank lines */ if (!compile_pattern(buffer, pcre_options, filename, linenumber)) goto EXIT2; } if (f != stdin) fclose(f); } /* Study the regular expressions, as we will be running them many times. Unless JIT has been explicitly disabled, arrange a stack for it to use. */ #ifdef SUPPORT_PCREGREP_JIT if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0) jit_stack = pcre_jit_stack_alloc(32*1024, 1024*1024); #endif for (j = 0; j < pattern_count; j++) { hints_list[j] = pcre_study(pattern_list[j], study_options, &error); if (error != NULL) { char s[16]; if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j); fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error); goto EXIT2; } hint_count++; #ifdef SUPPORT_PCREGREP_JIT if (jit_stack != NULL && hints_list[j] != NULL) pcre_assign_jit_stack(hints_list[j], NULL, jit_stack); #endif } /* If --match-limit or --recursion-limit was set, put the value(s) into the pcre_extra block for each pattern. */ if (match_limit > 0 || match_limit_recursion > 0) { for (j = 0; j < pattern_count; j++) { if (hints_list[j] == NULL) { hints_list[j] = malloc(sizeof(pcre_extra)); if (hints_list[j] == NULL) { fprintf(stderr, "pcregrep: malloc failed\n"); pcregrep_exit(2); } } if (match_limit > 0) { hints_list[j]->flags |= PCRE_EXTRA_MATCH_LIMIT; hints_list[j]->match_limit = match_limit; } if (match_limit_recursion > 0) { hints_list[j]->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; hints_list[j]->match_limit_recursion = match_limit_recursion; } } } /* If there are include or exclude patterns, compile them. */ if (exclude_pattern != NULL) { exclude_compiled = pcre_compile(exclude_pattern, 0, &error, &errptr, pcretables); if (exclude_compiled == NULL) { fprintf(stderr, "pcregrep: Error in 'exclude' regex at offset %d: %s\n", errptr, error); goto EXIT2; } } if (include_pattern != NULL) { include_compiled = pcre_compile(include_pattern, 0, &error, &errptr, pcretables); if (include_compiled == NULL) { fprintf(stderr, "pcregrep: Error in 'include' regex at offset %d: %s\n", errptr, error); goto EXIT2; } } if (exclude_dir_pattern != NULL) { exclude_dir_compiled = pcre_compile(exclude_dir_pattern, 0, &error, &errptr, pcretables); if (exclude_dir_compiled == NULL) { fprintf(stderr, "pcregrep: Error in 'exclude_dir' regex at offset %d: %s\n", errptr, error); goto EXIT2; } } if (include_dir_pattern != NULL) { include_dir_compiled = pcre_compile(include_dir_pattern, 0, &error, &errptr, pcretables); if (include_dir_compiled == NULL) { fprintf(stderr, "pcregrep: Error in 'include_dir' regex at offset %d: %s\n", errptr, error); goto EXIT2; } } /* If a file that contains a list of files to search has been specified, read it line by line and search the given files. Otherwise, if there are no further arguments, do the business on stdin and exit. */ if (file_list != NULL) { char buffer[PATBUFSIZE]; FILE *fl; if (strcmp(file_list, "-") == 0) fl = stdin; else { fl = fopen(file_list, "rb"); if (fl == NULL) { fprintf(stderr, "pcregrep: Failed to open %s: %s\n", file_list, strerror(errno)); goto EXIT2; } } while (fgets(buffer, PATBUFSIZE, fl) != NULL) { int frc; char *end = buffer + (int)strlen(buffer); while (end > buffer && isspace(end[-1])) end--; *end = 0; if (*buffer != 0) { frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE); if (frc > 1) rc = frc; else if (frc == 0 && rc == 1) rc = 0; } } if (fl != stdin) fclose (fl); } /* Do this only if there was no file list (and no file arguments). */ else if (i >= argc) { rc = pcregrep(stdin, FR_PLAIN, stdin_name, (filenames > FN_DEFAULT)? stdin_name : NULL); goto EXIT; } /* After handling file-list or if there are remaining arguments, work through them as files or directories. Pass in the fact that there is only one argument at top level - this suppresses the file name if the argument is not a directory and filenames are not otherwise forced. */ only_one_at_top = i == argc - 1 && file_list == NULL; for (; i < argc; i++) { int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE, only_one_at_top); if (frc > 1) rc = frc; else if (frc == 0 && rc == 1) rc = 0; } EXIT: #ifdef SUPPORT_PCREGREP_JIT if (jit_stack != NULL) pcre_jit_stack_free(jit_stack); #endif if (main_buffer != NULL) free(main_buffer); if (pattern_list != NULL) { for (i = 0; i < pattern_count; i++) free(pattern_list[i]); free(pattern_list); } if (hints_list != NULL) { for (i = 0; i < hint_count; i++) { if (hints_list[i] != NULL) pcre_free_study(hints_list[i]); } free(hints_list); } pcregrep_exit(rc); EXIT2: rc = 2; goto EXIT; } /* End of pcregrep */ pcre-8.31/pcre16_globals.c0000644000222100022210000000420111676645216012265 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_globals.c" /* End of pcre16_globals.c */ pcre-8.31/pcre_dfa_exec.c0000644000222100022210000036543711770363602012245 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language (but see below for why this module is different). Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_dfa_exec(), which is an alternative matching function that uses a sort of DFA algorithm (not a true FSM). This is NOT Perl-compatible, but it has advantages in certain applications. */ /* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved the performance of his patterns greatly. I could not use it as it stood, as it was not thread safe, and made assumptions about pattern sizes. Also, it caused test 7 to loop, and test 9 to crash with a segfault. The issue is the check for duplicate states, which is done by a simple linear search up the state list. (Grep for "duplicate" below to find the code.) For many patterns, there will never be many states active at one time, so a simple linear search is fine. In patterns that have many active states, it might be a bottleneck. The suggested code used an indexing scheme to remember which states had previously been used for each character, and avoided the linear search when it knew there was no chance of a duplicate. This was implemented when adding states to the state lists. I wrote some thread-safe, not-limited code to try something similar at the time of checking for duplicates (instead of when adding states), using index vectors on the stack. It did give a 13% improvement with one specially constructed pattern for certain subject strings, but on other strings and on many of the simpler patterns in the test suite it did worse. The major problem, I think, was the extra time to initialize the index. This had to be done for each call of internal_dfa_exec(). (The supplied patch used a static vector, initialized only once - I suspect this was the cause of the problems with the tests.) Overall, I concluded that the gains in some cases did not outweigh the losses in others, so I abandoned this code. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define NLBLOCK md /* Block containing newline information */ #define PSSTART start_subject /* Field containing processed string start */ #define PSEND end_subject /* Field containing processed string end */ #include "pcre_internal.h" /* For use to indent debugging output */ #define SP " " /************************************************* * Code parameters and static tables * *************************************************/ /* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes into others, under special conditions. A gap of 20 between the blocks should be enough. The resulting opcodes don't have to be less than 256 because they are never stored, so we push them well clear of the normal opcodes. */ #define OP_PROP_EXTRA 300 #define OP_EXTUNI_EXTRA 320 #define OP_ANYNL_EXTRA 340 #define OP_HSPACE_EXTRA 360 #define OP_VSPACE_EXTRA 380 /* This table identifies those opcodes that are followed immediately by a character that is to be tested in some way. This makes it possible to centralize the loading of these characters. In the case of Type * etc, the "character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a small value. Non-zero values in the table are the offsets from the opcode where the character is to be found. ***NOTE*** If the start of this table is modified, the three tables that follow must also be modified. */ static const pcre_uint8 coptable[] = { 0, /* End */ 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */ 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */ 0, 0, 0, /* Any, AllAny, Anybyte */ 0, 0, /* \P, \p */ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ 0, /* \X */ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ 1, /* Char */ 1, /* Chari */ 1, /* not */ 1, /* noti */ /* Positive single-char repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */ 1+IMM2_SIZE, /* exact */ 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */ 1+IMM2_SIZE, /* exact I */ 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ /* Negative single-char repeats - only for chars < 256 */ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */ 1+IMM2_SIZE, /* NOT exact */ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */ 1+IMM2_SIZE, /* NOT exact I */ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */ /* Positive type repeats */ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */ 1+IMM2_SIZE, /* Type exact */ 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */ /* Character class & ref repeats */ 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */ 0, 0, /* CRRANGE, CRMINRANGE */ 0, /* CLASS */ 0, /* NCLASS */ 0, /* XCLASS - variable length */ 0, /* REF */ 0, /* REFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ 0, /* Ket */ 0, /* KetRmax */ 0, /* KetRmin */ 0, /* KetRpos */ 0, /* Reverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ 0, 0, /* ONCE, ONCE_NC */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, NCREF */ 0, 0, /* RREF, NRREF */ 0, /* DEF */ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0 /* CLOSE, SKIPZERO */ }; /* This table identifies those opcodes that inspect a character. It is used to remember the fact that a character could have been inspected when the end of the subject is reached. ***NOTE*** If the start of this table is modified, the two tables that follow must also be modified. */ static const pcre_uint8 poptable[] = { 0, /* End */ 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ 1, 1, 1, /* Any, AllAny, Anybyte */ 1, 1, /* \P, \p */ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ 1, /* \X */ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ 1, /* Char */ 1, /* Chari */ 1, /* not */ 1, /* noti */ /* Positive single-char repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 1, 1, 1, /* upto, minupto, exact */ 1, 1, 1, 1, /* *+, ++, ?+, upto+ */ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ 1, 1, 1, /* upto I, minupto I, exact I */ 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */ /* Negative single-char repeats - only for chars < 256 */ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ 1, 1, 1, /* NOT upto, minupto, exact */ 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ 1, 1, 1, /* NOT upto I, minupto I, exact I */ 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */ /* Positive type repeats */ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ 1, 1, 1, /* Type upto, minupto, exact */ 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */ /* Character class & ref repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 1, 1, /* CRRANGE, CRMINRANGE */ 1, /* CLASS */ 1, /* NCLASS */ 1, /* XCLASS - variable length */ 0, /* REF */ 0, /* REFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ 0, /* Ket */ 0, /* KetRmax */ 0, /* KetRmin */ 0, /* KetRpos */ 0, /* Reverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ 0, 0, /* ONCE, ONCE_NC */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, NCREF */ 0, 0, /* RREF, NRREF */ 0, /* DEF */ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0 /* CLOSE, SKIPZERO */ }; /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, and \w */ static const pcre_uint8 toptable1[] = { 0, 0, 0, 0, 0, 0, ctype_digit, ctype_digit, ctype_space, ctype_space, ctype_word, ctype_word, 0, 0 /* OP_ANY, OP_ALLANY */ }; static const pcre_uint8 toptable2[] = { 0, 0, 0, 0, 0, 0, ctype_digit, 0, ctype_space, 0, ctype_word, 0, 1, 1 /* OP_ANY, OP_ALLANY */ }; /* Structure for holding data about a particular state, which is in effect the current data for an active path through the match tree. It must consist entirely of ints because the working vector we are passed, and which we put these structures in, is a vector of ints. */ typedef struct stateblock { int offset; /* Offset to opcode */ int count; /* Count for repeats */ int data; /* Some use extra data */ } stateblock; #define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int)) #ifdef PCRE_DEBUG /************************************************* * Print character string * *************************************************/ /* Character string printing function for debugging. Arguments: p points to string length number of bytes f where to print Returns: nothing */ static void pchars(const pcre_uchar *p, int length, FILE *f) { int c; while (length-- > 0) { if (isprint(c = *(p++))) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); } } #endif /************************************************* * Execute a Regular Expression - DFA engine * *************************************************/ /* This internal function applies a compiled pattern to a subject string, starting at a given point, using a DFA engine. This function is called from the external one, possibly multiple times if the pattern is not anchored. The function calls itself recursively for some kinds of subpattern. Arguments: md the match_data block with fixed information this_start_code the opening bracket of this subexpression's code current_subject where we currently are in the subject string start_offset start offset in the subject string offsets vector to contain the matching string offsets offsetcount size of same workspace vector of workspace wscount size of same rlevel function call recursion level Returns: > 0 => number of match offset pairs placed in offsets = 0 => offsets overflowed; longest matches are present -1 => failed to match < -1 => some kind of unexpected problem The following macros are used for adding states to the two state vectors (one for the current character, one for the following character). */ #define ADD_ACTIVE(x,y) \ if (active_count++ < wscount) \ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ else return PCRE_ERROR_DFA_WSSIZE #define ADD_ACTIVE_DATA(x,y,z) \ if (active_count++ < wscount) \ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ next_active_state->data = (z); \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ } \ else return PCRE_ERROR_DFA_WSSIZE #define ADD_NEW(x,y) \ if (new_count++ < wscount) \ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ next_new_state++; \ DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ else return PCRE_ERROR_DFA_WSSIZE #define ADD_NEW_DATA(x,y,z) \ if (new_count++ < wscount) \ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ next_new_state->data = (z); \ next_new_state++; \ DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \ (x), (y), (z), __LINE__)); \ } \ else return PCRE_ERROR_DFA_WSSIZE /* And now, here is the code */ static int internal_dfa_exec( dfa_match_data *md, const pcre_uchar *this_start_code, const pcre_uchar *current_subject, int start_offset, int *offsets, int offsetcount, int *workspace, int wscount, int rlevel) { stateblock *active_states, *new_states, *temp_states; stateblock *next_active_state, *next_new_state; const pcre_uint8 *ctypes, *lcc, *fcc; const pcre_uchar *ptr; const pcre_uchar *end_code, *first_op; dfa_recursion_info new_recursive; int active_count, new_count, match_count; /* Some fields in the md block are frequently referenced, so we load them into independent variables in the hope that this will perform better. */ const pcre_uchar *start_subject = md->start_subject; const pcre_uchar *end_subject = md->end_subject; const pcre_uchar *start_code = md->start_code; #ifdef SUPPORT_UTF BOOL utf = (md->poptions & PCRE_UTF8) != 0; #else BOOL utf = FALSE; #endif BOOL reset_could_continue = FALSE; rlevel++; offsetcount &= (-2); wscount -= 2; wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) / (2 * INTS_PER_STATEBLOCK); DPRINTF(("\n%.*s---------------------\n" "%.*sCall to internal_dfa_exec f=%d\n", rlevel*2-2, SP, rlevel*2-2, SP, rlevel)); ctypes = md->tables + ctypes_offset; lcc = md->tables + lcc_offset; fcc = md->tables + fcc_offset; match_count = PCRE_ERROR_NOMATCH; /* A negative number */ active_states = (stateblock *)(workspace + 2); next_new_state = new_states = active_states + wscount; new_count = 0; first_op = this_start_code + 1 + LINK_SIZE + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) ? IMM2_SIZE:0); /* The first thing in any (sub) pattern is a bracket of some sort. Push all the alternative states onto the list, and find out where the end is. This makes is possible to use this function recursively, when we want to stop at a matching internal ket rather than at the end. If the first opcode in the first alternative is OP_REVERSE, we are dealing with a backward assertion. In that case, we have to find out the maximum amount to move back, and set up each alternative appropriately. */ if (*first_op == OP_REVERSE) { int max_back = 0; int gone_back; end_code = this_start_code; do { int back = GET(end_code, 2+LINK_SIZE); if (back > max_back) max_back = back; end_code += GET(end_code, 1); } while (*end_code == OP_ALT); /* If we can't go back the amount required for the longest lookbehind pattern, go back as far as we can; some alternatives may still be viable. */ #ifdef SUPPORT_UTF /* In character mode we have to step back character by character */ if (utf) { for (gone_back = 0; gone_back < max_back; gone_back++) { if (current_subject <= start_subject) break; current_subject--; ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--); } } else #endif /* In byte-mode we can do this quickly. */ { gone_back = (current_subject - max_back < start_subject)? (int)(current_subject - start_subject) : max_back; current_subject -= gone_back; } /* Save the earliest consulted character */ if (current_subject < md->start_used_ptr) md->start_used_ptr = current_subject; /* Now we can process the individual branches. */ end_code = this_start_code; do { int back = GET(end_code, 2+LINK_SIZE); if (back <= gone_back) { int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE); ADD_NEW_DATA(-bstate, 0, gone_back - back); } end_code += GET(end_code, 1); } while (*end_code == OP_ALT); } /* This is the code for a "normal" subpattern (not a backward assertion). The start of a whole pattern is always one of these. If we are at the top level, we may be asked to restart matching from the same point that we reached for a previous partial match. We still have to scan through the top-level branches to find the end state. */ else { end_code = this_start_code; /* Restarting */ if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0) { do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT); new_count = workspace[1]; if (!workspace[0]) memcpy(new_states, active_states, new_count * sizeof(stateblock)); } /* Not restarting */ else { int length = 1 + LINK_SIZE + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) ? IMM2_SIZE:0); do { ADD_NEW((int)(end_code - start_code + length), 0); end_code += GET(end_code, 1); length = 1 + LINK_SIZE; } while (*end_code == OP_ALT); } } workspace[0] = 0; /* Bit indicating which vector is current */ DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code))); /* Loop for scanning the subject */ ptr = current_subject; for (;;) { int i, j; int clen, dlen; unsigned int c, d; int forced_fail = 0; BOOL partial_newline = FALSE; BOOL could_continue = reset_could_continue; reset_could_continue = FALSE; /* Make the new state list into the active state list and empty the new state list. */ temp_states = active_states; active_states = new_states; new_states = temp_states; active_count = new_count; new_count = 0; workspace[0] ^= 1; /* Remember for the restarting feature */ workspace[1] = active_count; #ifdef PCRE_DEBUG printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP); pchars(ptr, STRLEN_UC(ptr), stdout); printf("\"\n"); printf("%.*sActive states: ", rlevel*2-2, SP); for (i = 0; i < active_count; i++) printf("%d/%d ", active_states[i].offset, active_states[i].count); printf("\n"); #endif /* Set the pointers for adding new states */ next_active_state = active_states + active_count; next_new_state = new_states; /* Load the current character from the subject outside the loop, as many different states may want to look at it, and we assume that at least one will. */ if (ptr < end_subject) { clen = 1; /* Number of data items in the character */ #ifdef SUPPORT_UTF if (utf) { GETCHARLEN(c, ptr, clen); } else #endif /* SUPPORT_UTF */ c = *ptr; } else { clen = 0; /* This indicates the end of the subject */ c = NOTACHAR; /* This value should never actually be used */ } /* Scan up the active states and act on each one. The result of an action may be to add more states to the currently active list (e.g. on hitting a parenthesis) or it may be to put states on the new list, for considering when we move the character pointer on. */ for (i = 0; i < active_count; i++) { stateblock *current_state = active_states + i; BOOL caseless = FALSE; const pcre_uchar *code; int state_offset = current_state->offset; int count, codevalue, rrc; #ifdef PCRE_DEBUG printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset); if (clen == 0) printf("EOL\n"); else if (c > 32 && c < 127) printf("'%c'\n", c); else printf("0x%02x\n", c); #endif /* A negative offset is a special case meaning "hold off going to this (negated) state until the number of characters in the data field have been skipped". If the could_continue flag was passed over from a previous state, arrange for it to passed on. */ if (state_offset < 0) { if (current_state->data > 0) { DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP)); ADD_NEW_DATA(state_offset, current_state->count, current_state->data - 1); if (could_continue) reset_could_continue = TRUE; continue; } else { current_state->offset = state_offset = -state_offset; } } /* Check for a duplicate state with the same count, and skip if found. See the note at the head of this module about the possibility of improving performance here. */ for (j = 0; j < i; j++) { if (active_states[j].offset == state_offset && active_states[j].count == current_state->count) { DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP)); goto NEXT_ACTIVE_STATE; } } /* The state offset is the offset to the opcode */ code = start_code + state_offset; codevalue = *code; /* If this opcode inspects a character, but we are at the end of the subject, remember the fact for use when testing for a partial match. */ if (clen == 0 && poptable[codevalue] != 0) could_continue = TRUE; /* If this opcode is followed by an inline character, load it. It is tempting to test for the presence of a subject character here, but that is wrong, because sometimes zero repetitions of the subject are permitted. We also use this mechanism for opcodes such as OP_TYPEPLUS that take an argument that is not a data character - but is always one byte long because the values are small. We have to take special action to deal with \P, \p, \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert these ones to new opcodes. */ if (coptable[codevalue] > 0) { dlen = 1; #ifdef SUPPORT_UTF if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else #endif /* SUPPORT_UTF */ d = code[coptable[codevalue]]; if (codevalue >= OP_TYPESTAR) { switch(d) { case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM; case OP_NOTPROP: case OP_PROP: codevalue += OP_PROP_EXTRA; break; case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break; case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break; case OP_NOT_HSPACE: case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break; case OP_NOT_VSPACE: case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break; default: break; } } } else { dlen = 0; /* Not strictly necessary, but compilers moan */ d = NOTACHAR; /* if these variables are not set. */ } /* Now process the individual opcodes */ switch (codevalue) { /* ========================================================================== */ /* These cases are never obeyed. This is a fudge that causes a compile- time error if the vectors coptable or poptable, which are indexed by opcode, are not the correct length. It seems to be the only way to do such a check at compile time, as the sizeof() operator does not work in the C preprocessor. */ case OP_TABLE_LENGTH: case OP_TABLE_LENGTH + ((sizeof(coptable) == OP_TABLE_LENGTH) && (sizeof(poptable) == OP_TABLE_LENGTH)): break; /* ========================================================================== */ /* Reached a closing bracket. If not at the end of the pattern, carry on with the next opcode. For repeating opcodes, also add the repeat state. Note that KETRPOS will always be encountered at the end of the subpattern, because the possessive subpattern repeats are always handled using recursive calls. Thus, it never adds any new states. At the end of the (sub)pattern, unless we have an empty string and PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the start of the subject, save the match data, shifting up all previous matches so we always have the longest first. */ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: case OP_KETRPOS: if (code != end_code) { ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); if (codevalue != OP_KET) { ADD_ACTIVE(state_offset - GET(code, 1), 0); } } else { if (ptr > current_subject || ((md->moptions & PCRE_NOTEMPTY) == 0 && ((md->moptions & PCRE_NOTEMPTY_ATSTART) == 0 || current_subject > start_subject + md->start_offset))) { if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0; else if (match_count > 0 && ++match_count * 2 > offsetcount) match_count = 0; count = ((match_count == 0)? offsetcount : match_count * 2) - 2; if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int)); if (offsetcount >= 2) { offsets[0] = (int)(current_subject - start_subject); offsets[1] = (int)(ptr - start_subject); DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP, offsets[1] - offsets[0], (char *)current_subject)); } if ((md->moptions & PCRE_DFA_SHORTEST) != 0) { DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n" "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count, rlevel*2-2, SP)); return match_count; } } } break; /* ========================================================================== */ /* These opcodes add to the current list of states without looking at the current character. */ /*-----------------------------------------------------------------*/ case OP_ALT: do { code += GET(code, 1); } while (*code == OP_ALT); ADD_ACTIVE((int)(code - start_code), 0); break; /*-----------------------------------------------------------------*/ case OP_BRA: case OP_SBRA: do { ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); code += GET(code, 1); } while (*code == OP_ALT); break; /*-----------------------------------------------------------------*/ case OP_CBRA: case OP_SCBRA: ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0); code += GET(code, 1); while (*code == OP_ALT) { ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); code += GET(code, 1); } break; /*-----------------------------------------------------------------*/ case OP_BRAZERO: case OP_BRAMINZERO: ADD_ACTIVE(state_offset + 1, 0); code += 1 + GET(code, 2); while (*code == OP_ALT) code += GET(code, 1); ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); break; /*-----------------------------------------------------------------*/ case OP_SKIPZERO: code += 1 + GET(code, 2); while (*code == OP_ALT) code += GET(code, 1); ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); break; /*-----------------------------------------------------------------*/ case OP_CIRC: if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_CIRCM: if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) || (ptr != end_subject && WAS_NEWLINE(ptr))) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_EOD: if (ptr >= end_subject) { if ((md->moptions & PCRE_PARTIAL_HARD) != 0) could_continue = TRUE; else { ADD_ACTIVE(state_offset + 1, 0); } } break; /*-----------------------------------------------------------------*/ case OP_SOD: if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_SOM: if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); } break; /* ========================================================================== */ /* These opcodes inspect the next subject character, and sometimes the previous one as well, but do not have an argument. The variable clen contains the length of the current character and is zero if we are at the end of the subject. */ /*-----------------------------------------------------------------*/ case OP_ANY: if (clen > 0 && !IS_NEWLINE(ptr)) { if (ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { could_continue = partial_newline = TRUE; } else { ADD_NEW(state_offset + 1, 0); } } break; /*-----------------------------------------------------------------*/ case OP_ALLANY: if (clen > 0) { ADD_NEW(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_EODN: if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0) could_continue = TRUE; else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen)) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_DOLL: if ((md->moptions & PCRE_NOTEOL) == 0) { if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0) could_continue = TRUE; else if (clen == 0 || ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) && (ptr == end_subject - md->nllen) )) { ADD_ACTIVE(state_offset + 1, 0); } else if (ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { if ((md->moptions & PCRE_PARTIAL_HARD) != 0) { reset_could_continue = TRUE; ADD_NEW_DATA(-(state_offset + 1), 0, 1); } else could_continue = partial_newline = TRUE; } } break; /*-----------------------------------------------------------------*/ case OP_DOLLM: if ((md->moptions & PCRE_NOTEOL) == 0) { if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0) could_continue = TRUE; else if (clen == 0 || ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr))) { ADD_ACTIVE(state_offset + 1, 0); } else if (ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { if ((md->moptions & PCRE_PARTIAL_HARD) != 0) { reset_could_continue = TRUE; ADD_NEW_DATA(-(state_offset + 1), 0, 1); } else could_continue = partial_newline = TRUE; } } else if (IS_NEWLINE(ptr)) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_DIGIT: case OP_WHITESPACE: case OP_WORDCHAR: if (clen > 0 && c < 256 && ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0) { ADD_NEW(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_NOT_DIGIT: case OP_NOT_WHITESPACE: case OP_NOT_WORDCHAR: if (clen > 0 && (c >= 256 || ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)) { ADD_NEW(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: { int left_word, right_word; if (ptr > start_subject) { const pcre_uchar *temp = ptr - 1; if (temp < md->start_used_ptr) md->start_used_ptr = temp; #ifdef SUPPORT_UTF if (utf) { BACKCHAR(temp); } #endif GETCHARTEST(d, temp); #ifdef SUPPORT_UCP if ((md->poptions & PCRE_UCP) != 0) { if (d == '_') left_word = TRUE; else { int cat = UCD_CATEGORY(d); left_word = (cat == ucp_L || cat == ucp_N); } } else #endif left_word = d < 256 && (ctypes[d] & ctype_word) != 0; } else left_word = FALSE; if (clen > 0) { #ifdef SUPPORT_UCP if ((md->poptions & PCRE_UCP) != 0) { if (c == '_') right_word = TRUE; else { int cat = UCD_CATEGORY(c); right_word = (cat == ucp_L || cat == ucp_N); } } else #endif right_word = c < 256 && (ctypes[c] & ctype_word) != 0; } else right_word = FALSE; if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY)) { ADD_ACTIVE(state_offset + 1, 0); } } break; /*-----------------------------------------------------------------*/ /* Check the next character by Unicode property. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ #ifdef SUPPORT_UCP case OP_PROP: case OP_NOTPROP: if (clen > 0) { BOOL OK; const ucd_record * prop = GET_UCD(c); switch(code[1]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt; break; case PT_GC: OK = PRIV(ucp_gentype)[prop->chartype] == code[2]; break; case PT_PC: OK = prop->chartype == code[2]; break; case PT_SC: OK = prop->script == code[2]; break; /* These are specials for combination cases. */ case PT_ALNUM: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); } } break; #endif /* ========================================================================== */ /* These opcodes likewise inspect the subject character, but have an argument that is not a data character. It is one of these opcodes: OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE, OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */ case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { if (d == OP_ANY && ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { could_continue = partial_newline = TRUE; } else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (count > 0 && codevalue == OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW(state_offset, count); } } break; /*-----------------------------------------------------------------*/ case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { if (d == OP_ANY && ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { could_continue = partial_newline = TRUE; } else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (codevalue == OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset + 2, 0); } } break; /*-----------------------------------------------------------------*/ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { if (d == OP_ANY && ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { could_continue = partial_newline = TRUE; } else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (codevalue == OP_TYPEPOSSTAR) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset, 0); } } break; /*-----------------------------------------------------------------*/ case OP_TYPEEXACT: count = current_state->count; /* Number already matched */ if (clen > 0) { if (d == OP_ANY && ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { could_continue = partial_newline = TRUE; } else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); } else { ADD_NEW(state_offset, count); } } } break; /*-----------------------------------------------------------------*/ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); count = current_state->count; /* Number already matched */ if (clen > 0) { if (d == OP_ANY && ptr + 1 >= md->end_subject && (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { could_continue = partial_newline = TRUE; } else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (codevalue == OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } } break; /* ========================================================================== */ /* These are virtual opcodes that are used when something like OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its argument. It keeps the code above fast for the other cases. The argument is in the d variable. */ #ifdef SUPPORT_UCP case OP_PROP_EXTRA + OP_TYPEPLUS: case OP_PROP_EXTRA + OP_TYPEMINPLUS: case OP_PROP_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); } if (clen > 0) { BOOL OK; const ucd_record * prop = GET_UCD(c); switch(code[2]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt; break; case PT_GC: OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; break; case PT_PC: OK = prop->chartype == code[3]; break; case PT_SC: OK = prop->script == code[3]; break; /* These are specials for combination cases. */ case PT_ALNUM: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (d == OP_PROP)) { if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW(state_offset, count); } } break; /*-----------------------------------------------------------------*/ case OP_EXTUNI_EXTRA + OP_TYPEPLUS: case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS: case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } while (nptr < end_subject) { int nd; int ndlen = 1; GETCHARLEN(nd, nptr, ndlen); if (UCD_CATEGORY(nd) != ucp_M) break; ncount++; nptr += ndlen; } count++; ADD_NEW_DATA(-state_offset, count, ncount); } break; #endif /*-----------------------------------------------------------------*/ case OP_ANYNL_EXTRA + OP_TYPEPLUS: case OP_ANYNL_EXTRA + OP_TYPEMINPLUS: case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { int ncount = 0; switch (c) { case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; goto ANYNL01; case 0x000d: if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ ANYNL01: case 0x000a: if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW_DATA(-state_offset, count, ncount); break; default: break; } } break; /*-----------------------------------------------------------------*/ case OP_VSPACE_EXTRA + OP_TYPEPLUS: case OP_VSPACE_EXTRA + OP_TYPEMINPLUS: case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { BOOL OK; switch (c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_VSPACE)) { if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW_DATA(-state_offset, count, 0); } } break; /*-----------------------------------------------------------------*/ case OP_HSPACE_EXTRA + OP_TYPEPLUS: case OP_HSPACE_EXTRA + OP_TYPEMINPLUS: case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { BOOL OK; switch (c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_HSPACE)) { if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW_DATA(-state_offset, count, 0); } } break; /*-----------------------------------------------------------------*/ #ifdef SUPPORT_UCP case OP_PROP_EXTRA + OP_TYPEQUERY: case OP_PROP_EXTRA + OP_TYPEMINQUERY: case OP_PROP_EXTRA + OP_TYPEPOSQUERY: count = 4; goto QS1; case OP_PROP_EXTRA + OP_TYPESTAR: case OP_PROP_EXTRA + OP_TYPEMINSTAR: case OP_PROP_EXTRA + OP_TYPEPOSSTAR: count = 0; QS1: ADD_ACTIVE(state_offset + 4, 0); if (clen > 0) { BOOL OK; const ucd_record * prop = GET_UCD(c); switch(code[2]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt; break; case PT_GC: OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; break; case PT_PC: OK = prop->chartype == code[3]; break; case PT_SC: OK = prop->script == code[3]; break; /* These are specials for combination cases. */ case PT_ALNUM: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (d == OP_PROP)) { if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset + count, 0); } } break; /*-----------------------------------------------------------------*/ case OP_EXTUNI_EXTRA + OP_TYPEQUERY: case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY: case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS2; case OP_EXTUNI_EXTRA + OP_TYPESTAR: case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR: case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR: count = 0; QS2: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } while (nptr < end_subject) { int nd; int ndlen = 1; GETCHARLEN(nd, nptr, ndlen); if (UCD_CATEGORY(nd) != ucp_M) break; ncount++; nptr += ndlen; } ADD_NEW_DATA(-(state_offset + count), 0, ncount); } break; #endif /*-----------------------------------------------------------------*/ case OP_ANYNL_EXTRA + OP_TYPEQUERY: case OP_ANYNL_EXTRA + OP_TYPEMINQUERY: case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS3; case OP_ANYNL_EXTRA + OP_TYPESTAR: case OP_ANYNL_EXTRA + OP_TYPEMINSTAR: case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR: count = 0; QS3: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { int ncount = 0; switch (c) { case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; goto ANYNL02; case 0x000d: if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ ANYNL02: case 0x000a: if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW_DATA(-(state_offset + count), 0, ncount); break; default: break; } } break; /*-----------------------------------------------------------------*/ case OP_VSPACE_EXTRA + OP_TYPEQUERY: case OP_VSPACE_EXTRA + OP_TYPEMINQUERY: case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS4; case OP_VSPACE_EXTRA + OP_TYPESTAR: case OP_VSPACE_EXTRA + OP_TYPEMINSTAR: case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR: count = 0; QS4: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { BOOL OK; switch (c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_VSPACE)) { if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW_DATA(-(state_offset + count), 0, 0); } } break; /*-----------------------------------------------------------------*/ case OP_HSPACE_EXTRA + OP_TYPEQUERY: case OP_HSPACE_EXTRA + OP_TYPEMINQUERY: case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS5; case OP_HSPACE_EXTRA + OP_TYPESTAR: case OP_HSPACE_EXTRA + OP_TYPEMINSTAR: case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR: count = 0; QS5: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { BOOL OK; switch (c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_HSPACE)) { if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW_DATA(-(state_offset + count), 0, 0); } } break; /*-----------------------------------------------------------------*/ #ifdef SUPPORT_UCP case OP_PROP_EXTRA + OP_TYPEEXACT: case OP_PROP_EXTRA + OP_TYPEUPTO: case OP_PROP_EXTRA + OP_TYPEMINUPTO: case OP_PROP_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { BOOL OK; const ucd_record * prop = GET_UCD(c); switch(code[1 + IMM2_SIZE + 1]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt; break; case PT_GC: OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2]; break; case PT_PC: OK = prop->chartype == code[1 + IMM2_SIZE + 2]; break; case PT_SC: OK = prop->script == code[1 + IMM2_SIZE + 2]; break; /* These are specials for combination cases. */ case PT_ALNUM: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (d == OP_PROP)) { if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); } else { ADD_NEW(state_offset, count); } } } break; /*-----------------------------------------------------------------*/ case OP_EXTUNI_EXTRA + OP_TYPEEXACT: case OP_EXTUNI_EXTRA + OP_TYPEUPTO: case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO: case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } while (nptr < end_subject) { int nd; int ndlen = 1; GETCHARLEN(nd, nptr, ndlen); if (UCD_CATEGORY(nd) != ucp_M) break; ncount++; nptr += ndlen; } if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } } break; #endif /*-----------------------------------------------------------------*/ case OP_ANYNL_EXTRA + OP_TYPEEXACT: case OP_ANYNL_EXTRA + OP_TYPEUPTO: case OP_ANYNL_EXTRA + OP_TYPEMINUPTO: case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { int ncount = 0; switch (c) { case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; goto ANYNL03; case 0x000d: if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ ANYNL03: case 0x000a: if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } break; default: break; } } break; /*-----------------------------------------------------------------*/ case OP_VSPACE_EXTRA + OP_TYPEEXACT: case OP_VSPACE_EXTRA + OP_TYPEUPTO: case OP_VSPACE_EXTRA + OP_TYPEMINUPTO: case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { BOOL OK; switch (c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: OK = TRUE; break; default: OK = FALSE; } if (OK == (d == OP_VSPACE)) { if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } } } break; /*-----------------------------------------------------------------*/ case OP_HSPACE_EXTRA + OP_TYPEEXACT: case OP_HSPACE_EXTRA + OP_TYPEUPTO: case OP_HSPACE_EXTRA + OP_TYPEMINUPTO: case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { BOOL OK; switch (c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_HSPACE)) { if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } } } break; /* ========================================================================== */ /* These opcodes are followed by a character that is usually compared to the current subject character; it is loaded into d. We still get here even if there is no subject character, because in some cases zero repetitions are permitted. */ /*-----------------------------------------------------------------*/ case OP_CHAR: if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_CHARI: if (clen == 0) break; #ifdef SUPPORT_UTF if (utf) { if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else { unsigned int othercase; if (c < 128) othercase = fcc[c]; else /* If we have Unicode property support, we can use it to test the other case of the character. */ #ifdef SUPPORT_UCP othercase = UCD_OTHERCASE(c); #else othercase = NOTACHAR; #endif if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); } } } else #endif /* SUPPORT_UTF */ /* Not UTF mode */ { if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d)) { ADD_NEW(state_offset + 2, 0); } } break; #ifdef SUPPORT_UCP /*-----------------------------------------------------------------*/ /* This is a tricky one because it can match more than one character. Find out how many characters to skip, and then set up a negative state to wait for them to pass before continuing. */ case OP_EXTUNI: if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { const pcre_uchar *nptr = ptr + clen; int ncount = 0; while (nptr < end_subject) { int nclen = 1; GETCHARLEN(c, nptr, nclen); if (UCD_CATEGORY(c) != ucp_M) break; ncount++; nptr += nclen; } if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; ADD_NEW_DATA(-(state_offset + 1), 0, ncount); } break; #endif /*-----------------------------------------------------------------*/ /* This is a tricky like EXTUNI because it too can match more than one character (when CR is followed by LF). In this case, set up a negative state to wait for one character to pass before continuing. */ case OP_ANYNL: if (clen > 0) switch(c) { case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; case 0x000a: ADD_NEW(state_offset + 1, 0); break; case 0x000d: if (ptr + 1 >= end_subject) { ADD_NEW(state_offset + 1, 0); if ((md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; } else if (ptr[1] == 0x0a) { ADD_NEW_DATA(-(state_offset + 1), 0, 1); } else { ADD_NEW(state_offset + 1, 0); } break; } break; /*-----------------------------------------------------------------*/ case OP_NOT_VSPACE: if (clen > 0) switch(c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: break; default: ADD_NEW(state_offset + 1, 0); break; } break; /*-----------------------------------------------------------------*/ case OP_VSPACE: if (clen > 0) switch(c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: ADD_NEW(state_offset + 1, 0); break; default: break; } break; /*-----------------------------------------------------------------*/ case OP_NOT_HSPACE: if (clen > 0) switch(c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; default: ADD_NEW(state_offset + 1, 0); break; } break; /*-----------------------------------------------------------------*/ case OP_HSPACE: if (clen > 0) switch(c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ ADD_NEW(state_offset + 1, 0); break; } break; /*-----------------------------------------------------------------*/ /* Match a negated single character casefully. */ case OP_NOT: if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); } break; /*-----------------------------------------------------------------*/ /* Match a negated single character caselessly. */ case OP_NOTI: if (clen > 0) { unsigned int otherd; #ifdef SUPPORT_UTF if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF */ otherd = TABLE_GET(d, fcc, d); if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); } } break; /*-----------------------------------------------------------------*/ case OP_PLUSI: case OP_MINPLUSI: case OP_POSPLUSI: case OP_NOTPLUSI: case OP_NOTMINPLUSI: case OP_NOTPOSPLUSI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; /* Fall through */ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); } if (clen > 0) { unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF */ otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (count > 0 && (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS)) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW(state_offset, count); } } break; /*-----------------------------------------------------------------*/ case OP_QUERYI: case OP_MINQUERYI: case OP_POSQUERYI: case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; /* Fall through */ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTPOSQUERY: ADD_ACTIVE(state_offset + dlen + 1, 0); if (clen > 0) { unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF */ otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset + dlen + 1, 0); } } break; /*-----------------------------------------------------------------*/ case OP_STARI: case OP_MINSTARI: case OP_POSSTARI: case OP_NOTSTARI: case OP_NOTMINSTARI: case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPOSSTAR: ADD_ACTIVE(state_offset + dlen + 1, 0); if (clen > 0) { unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF */ otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset, 0); } } break; /*-----------------------------------------------------------------*/ case OP_EXACTI: case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; /* Fall through */ case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ if (clen > 0) { unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF */ otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } } break; /*-----------------------------------------------------------------*/ case OP_UPTOI: case OP_MINUPTOI: case OP_POSUPTOI: case OP_NOTUPTOI: case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; /* Fall through */ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTPOSUPTO: ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0); count = current_state->count; /* Number already matched */ if (clen > 0) { unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF */ otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } } break; /* ========================================================================== */ /* These are the class-handling opcodes */ case OP_CLASS: case OP_NCLASS: case OP_XCLASS: { BOOL isinclass = FALSE; int next_state_offset; const pcre_uchar *ecode; /* For a simple class, there is always just a 32-byte table, and we can set isinclass from it. */ if (codevalue != OP_XCLASS) { ecode = code + 1 + (32 / sizeof(pcre_uchar)); if (clen > 0) { isinclass = (c > 255)? (codevalue == OP_NCLASS) : ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0); } } /* An extended class may have a table or a list of single characters, ranges, or both, and it may be positive or negative. There's a function that sorts all this out. */ else { ecode = code + GET(code, 1); if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf); } /* At this point, isinclass is set for all kinds of class, and ecode points to the byte after the end of the class. If there is a quantifier, this is where it will be. */ next_state_offset = (int)(ecode - start_code); switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: ADD_ACTIVE(next_state_offset + 1, 0); if (isinclass) { ADD_NEW(state_offset, 0); } break; case OP_CRPLUS: case OP_CRMINPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); } if (isinclass) { count++; ADD_NEW(state_offset, count); } break; case OP_CRQUERY: case OP_CRMINQUERY: ADD_ACTIVE(next_state_offset + 1, 0); if (isinclass) { ADD_NEW(next_state_offset + 1, 0); } break; case OP_CRRANGE: case OP_CRMINRANGE: count = current_state->count; /* Already matched */ if (count >= GET2(ecode, 1)) { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } if (isinclass) { int max = GET2(ecode, 1 + IMM2_SIZE); if (++count >= max && max != 0) /* Max 0 => no limit */ { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } break; default: if (isinclass) { ADD_NEW(next_state_offset, 0); } break; } } break; /* ========================================================================== */ /* These are the opcodes for fancy brackets of various kinds. We have to use recursion in order to handle them. The "always failing" assertion (?!) is optimised to OP_FAIL when compiling, so we have to support that, though the other "backtracking verbs" are not supported. */ case OP_FAIL: forced_fail++; /* Count FAILs for multiple states */ break; case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: { int rc; int local_offsets[2]; int local_workspace[1000]; const pcre_uchar *endasscode = code + GET(code, 1); while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); rc = internal_dfa_exec( md, /* static match data */ code, /* this subexpression's code */ ptr, /* where we currently are */ (int)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ rlevel); /* function recursion level */ if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } } break; /*-----------------------------------------------------------------*/ case OP_COND: case OP_SCOND: { int local_offsets[1000]; int local_workspace[1000]; int codelink = GET(code, 1); int condcode; /* Because of the way auto-callout works during compile, a callout item is inserted between OP_COND and an assertion condition. This does not happen for the other conditions. */ if (code[LINK_SIZE+1] == OP_CALLOUT) { rrc = 0; if (PUBL(callout) != NULL) { PUBL(callout_block) cb; cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = code[LINK_SIZE+2]; cb.offset_vector = offsets; #ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)start_subject; #else cb.subject = (PCRE_SPTR16)start_subject; #endif cb.subject_length = (int)(end_subject - start_subject); cb.start_match = (int)(current_subject - start_subject); cb.current_position = (int)(ptr - start_subject); cb.pattern_position = GET(code, LINK_SIZE + 3); cb.next_item_length = GET(code, 3 + 2*LINK_SIZE); cb.capture_top = 1; cb.capture_last = -1; cb.callout_data = md->callout_data; cb.mark = NULL; /* No (*MARK) support */ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */ } if (rrc > 0) break; /* Fail this thread */ code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */ } condcode = code[LINK_SIZE+1]; /* Back reference conditions are not supported */ if (condcode == OP_CREF || condcode == OP_NCREF) return PCRE_ERROR_DFA_UCOND; /* The DEFINE condition is always false */ if (condcode == OP_DEF) { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } /* The only supported version of OP_RREF is for the value RREF_ANY, which means "test if in any recursion". We can't test for specifically recursed groups. */ else if (condcode == OP_RREF || condcode == OP_NRREF) { int value = GET2(code, LINK_SIZE + 2); if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND; if (md->recursive != NULL) { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } } /* Otherwise, the condition is an assertion */ else { int rc; const pcre_uchar *asscode = code + LINK_SIZE + 1; const pcre_uchar *endasscode = asscode + GET(asscode, 1); while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); rc = internal_dfa_exec( md, /* fixed match data */ asscode, /* this subexpression's code */ ptr, /* where we currently are */ (int)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ rlevel); /* function recursion level */ if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == (condcode == OP_ASSERT || condcode == OP_ASSERTBACK)) { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } } } break; /*-----------------------------------------------------------------*/ case OP_RECURSE: { dfa_recursion_info *ri; int local_offsets[1000]; int local_workspace[1000]; const pcre_uchar *callpat = start_code + GET(code, 1); int recno = (callpat == md->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); int rc; DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP)); /* Check for repeating a recursion without advancing the subject pointer. This should catch convoluted mutual recursions. (Some simple cases are caught at compile time.) */ for (ri = md->recursive; ri != NULL; ri = ri->prevrec) if (recno == ri->group_num && ptr == ri->subject_position) return PCRE_ERROR_RECURSELOOP; /* Remember this recursion and where we started it so as to catch infinite loops. */ new_recursive.group_num = recno; new_recursive.subject_position = ptr; new_recursive.prevrec = md->recursive; md->recursive = &new_recursive; rc = internal_dfa_exec( md, /* fixed match data */ callpat, /* this subexpression's code */ ptr, /* where we currently are */ (int)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ rlevel); /* function recursion level */ md->recursive = new_recursive.prevrec; /* Done this recursion */ DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP, rc)); /* Ran out of internal offsets */ if (rc == 0) return PCRE_ERROR_DFA_RECURSE; /* For each successful matched substring, set up the next state with a count of characters to skip before trying it. Note that the count is in characters, not bytes. */ if (rc > 0) { for (rc = rc*2 - 2; rc >= 0; rc -= 2) { int charcount = local_offsets[rc+1] - local_offsets[rc]; #ifdef SUPPORT_UTF if (utf) { const pcre_uchar *p = start_subject + local_offsets[rc]; const pcre_uchar *pp = start_subject + local_offsets[rc+1]; while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--; } #endif if (charcount > 0) { ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1)); } else { ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0); } } } else if (rc != PCRE_ERROR_NOMATCH) return rc; } break; /*-----------------------------------------------------------------*/ case OP_BRAPOS: case OP_SBRAPOS: case OP_CBRAPOS: case OP_SCBRAPOS: case OP_BRAPOSZERO: { int charcount, matched_count; const pcre_uchar *local_ptr = ptr; BOOL allow_zero; if (codevalue == OP_BRAPOSZERO) { allow_zero = TRUE; codevalue = *(++code); /* Codevalue will be one of above BRAs */ } else allow_zero = FALSE; /* Loop to match the subpattern as many times as possible as if it were a complete pattern. */ for (matched_count = 0;; matched_count++) { int local_offsets[2]; int local_workspace[1000]; int rc = internal_dfa_exec( md, /* fixed match data */ code, /* this subexpression's code */ local_ptr, /* where we currently are */ (int)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ rlevel); /* function recursion level */ /* Failed to match */ if (rc < 0) { if (rc != PCRE_ERROR_NOMATCH) return rc; break; } /* Matched: break the loop if zero characters matched. */ charcount = local_offsets[1] - local_offsets[0]; if (charcount == 0) break; local_ptr += charcount; /* Advance temporary position ptr */ } /* At this point we have matched the subpattern matched_count times, and local_ptr is pointing to the character after the end of the last match. */ if (matched_count > 0 || allow_zero) { const pcre_uchar *end_subpattern = code; int next_state_offset; do { end_subpattern += GET(end_subpattern, 1); } while (*end_subpattern == OP_ALT); next_state_offset = (int)(end_subpattern - start_code + LINK_SIZE + 1); /* Optimization: if there are no more active states, and there are no new states yet set up, then skip over the subject string right here, to save looping. Otherwise, set up the new state to swing into action when the end of the matched substring is reached. */ if (i + 1 >= active_count && new_count == 0) { ptr = local_ptr; clen = 0; ADD_NEW(next_state_offset, 0); } else { const pcre_uchar *p = ptr; const pcre_uchar *pp = local_ptr; charcount = (int)(pp - p); #ifdef SUPPORT_UTF if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--; #endif ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); } } } break; /*-----------------------------------------------------------------*/ case OP_ONCE: case OP_ONCE_NC: { int local_offsets[2]; int local_workspace[1000]; int rc = internal_dfa_exec( md, /* fixed match data */ code, /* this subexpression's code */ ptr, /* where we currently are */ (int)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ rlevel); /* function recursion level */ if (rc >= 0) { const pcre_uchar *end_subpattern = code; int charcount = local_offsets[1] - local_offsets[0]; int next_state_offset, repeat_state_offset; do { end_subpattern += GET(end_subpattern, 1); } while (*end_subpattern == OP_ALT); next_state_offset = (int)(end_subpattern - start_code + LINK_SIZE + 1); /* If the end of this subpattern is KETRMAX or KETRMIN, we must arrange for the repeat state also to be added to the relevant list. Calculate the offset, or set -1 for no repeat. */ repeat_state_offset = (*end_subpattern == OP_KETRMAX || *end_subpattern == OP_KETRMIN)? (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1; /* If we have matched an empty string, add the next state at the current character pointer. This is important so that the duplicate checking kicks in, which is what breaks infinite loops that match an empty string. */ if (charcount == 0) { ADD_ACTIVE(next_state_offset, 0); } /* Optimization: if there are no more active states, and there are no new states yet set up, then skip over the subject string right here, to save looping. Otherwise, set up the new state to swing into action when the end of the matched substring is reached. */ else if (i + 1 >= active_count && new_count == 0) { ptr += charcount; clen = 0; ADD_NEW(next_state_offset, 0); /* If we are adding a repeat state at the new character position, we must fudge things so that it is the only current state. Otherwise, it might be a duplicate of one we processed before, and that would cause it to be skipped. */ if (repeat_state_offset >= 0) { next_active_state = active_states; active_count = 0; i = -1; ADD_ACTIVE(repeat_state_offset, 0); } } else { #ifdef SUPPORT_UTF if (utf) { const pcre_uchar *p = start_subject + local_offsets[0]; const pcre_uchar *pp = start_subject + local_offsets[1]; while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--; } #endif ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); if (repeat_state_offset >= 0) { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); } } } else if (rc != PCRE_ERROR_NOMATCH) return rc; } break; /* ========================================================================== */ /* Handle callouts */ case OP_CALLOUT: rrc = 0; if (PUBL(callout) != NULL) { PUBL(callout_block) cb; cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = code[1]; cb.offset_vector = offsets; #ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)start_subject; #else cb.subject = (PCRE_SPTR16)start_subject; #endif cb.subject_length = (int)(end_subject - start_subject); cb.start_match = (int)(current_subject - start_subject); cb.current_position = (int)(ptr - start_subject); cb.pattern_position = GET(code, 2); cb.next_item_length = GET(code, 2 + LINK_SIZE); cb.capture_top = 1; cb.capture_last = -1; cb.callout_data = md->callout_data; cb.mark = NULL; /* No (*MARK) support */ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */ } if (rrc == 0) { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); } break; /* ========================================================================== */ default: /* Unsupported opcode */ return PCRE_ERROR_DFA_UITEM; } NEXT_ACTIVE_STATE: continue; } /* End of loop scanning active states */ /* We have finished the processing at the current subject character. If no new states have been set for the next character, we have found all the matches that we are going to find. If we are at the top level and partial matching has been requested, check for appropriate conditions. The "forced_ fail" variable counts the number of (*F) encountered for the character. If it is equal to the original active_count (saved in workspace[1]) it means that (*F) was found on every active state. In this case we don't want to give a partial match. The "could_continue" variable is true if a state could have continued but for the fact that the end of the subject was reached. */ if (new_count <= 0) { if (rlevel == 1 && /* Top level, and */ could_continue && /* Some could go on, and */ forced_fail != workspace[1] && /* Not all forced fail & */ ( /* either... */ (md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */ || /* or... */ ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */ match_count < 0) /* no matches */ ) && /* And... */ ( partial_newline || /* Either partial NL */ ( /* or ... */ ptr >= end_subject && /* End of subject and */ ptr > md->start_used_ptr) /* Inspected non-empty string */ ) ) { if (offsetcount >= 2) { offsets[0] = (int)(md->start_used_ptr - start_subject); offsets[1] = (int)(end_subject - start_subject); } match_count = PCRE_ERROR_PARTIAL; } DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n" "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count, rlevel*2-2, SP)); break; /* In effect, "return", but see the comment below */ } /* One or more states are active for the next character. */ ptr += clen; /* Advance to next subject character */ } /* Loop to move along the subject string */ /* Control gets here from "break" a few lines above. We do it this way because if we use "return" above, we have compiler trouble. Some compilers warn if there's nothing here because they think the function doesn't return a value. On the other hand, if we put a dummy statement here, some more clever compilers complain that it can't be reached. Sigh. */ return match_count; } /************************************************* * Execute a Regular Expression - DFA engine * *************************************************/ /* This external function applies a compiled re to a subject string using a DFA engine. This function calls the internal function multiple times if the pattern is not anchored. Arguments: argument_re points to the compiled expression extra_data points to extra data or is NULL subject points to the subject string length length of subject string (may contain binary zeros) start_offset where to start in the subject string options option bits offsets vector of match offsets offsetcount size of same workspace workspace vector wscount size of same Returns: > 0 => number of match offset pairs placed in offsets = 0 => offsets overflowed; longest matches are present -1 => failed to match < -1 => some kind of unexpected problem */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data, const char *subject, int length, int start_offset, int options, int *offsets, int offsetcount, int *workspace, int wscount) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, int offsetcount, int *workspace, int wscount) #endif { REAL_PCRE *re = (REAL_PCRE *)argument_re; dfa_match_data match_block; dfa_match_data *md = &match_block; BOOL utf, anchored, startline, firstline; const pcre_uchar *current_subject, *end_subject; const pcre_study_data *study = NULL; const pcre_uchar *req_char_ptr; const pcre_uint8 *start_bits = NULL; BOOL has_first_char = FALSE; BOOL has_req_char = FALSE; pcre_uchar first_char = 0; pcre_uchar first_char2 = 0; pcre_uchar req_char = 0; pcre_uchar req_char2 = 0; int newline; /* Plausibility checks */ if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; if (re == NULL || subject == NULL || workspace == NULL || (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE; if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; /* Check that the first field in the block is the magic number. If it is not, return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which means that the pattern is likely compiled with different endianness. */ if (re->magic_number != MAGIC_NUMBER) return re->magic_number == REVERSED_MAGIC_NUMBER? PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; /* If restarting after a partial match, do some sanity checks on the contents of the workspace. */ if ((options & PCRE_DFA_RESTART) != 0) { if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 || workspace[1] > (wscount - 2)/INTS_PER_STATEBLOCK) return PCRE_ERROR_DFA_BADRESTART; } /* Set up study, callout, and table data */ md->tables = re->tables; md->callout_data = NULL; if (extra_data != NULL) { unsigned int flags = extra_data->flags; if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT; if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0) return PCRE_ERROR_DFA_UMLIMIT; if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) md->callout_data = extra_data->callout_data; if ((flags & PCRE_EXTRA_TABLES) != 0) md->tables = extra_data->tables; } /* Set some local values */ current_subject = (const pcre_uchar *)subject + start_offset; end_subject = (const pcre_uchar *)subject + length; req_char_ptr = current_subject - 1; #ifdef SUPPORT_UTF /* PCRE_UTF16 has the same value as PCRE_UTF8. */ utf = (re->options & PCRE_UTF8) != 0; #else utf = FALSE; #endif anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 || (re->options & PCRE_ANCHORED) != 0; /* The remaining fixed data for passing around. */ md->start_code = (const pcre_uchar *)argument_re + re->name_table_offset + re->name_count * re->name_entry_size; md->start_subject = (const pcre_uchar *)subject; md->end_subject = end_subject; md->start_offset = start_offset; md->moptions = options; md->poptions = re->options; /* If the BSR option is not set at match time, copy what was set at compile time. */ if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0) { if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0) md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE); #ifdef BSR_ANYCRLF else md->moptions |= PCRE_BSR_ANYCRLF; #endif } /* Handle different types of newline. The three bits give eight cases. If nothing is set at run time, whatever was used at compile time applies. */ switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) & PCRE_NEWLINE_BITS) { case 0: newline = NEWLINE; break; /* Compile-time default */ case PCRE_NEWLINE_CR: newline = CHAR_CR; break; case PCRE_NEWLINE_LF: newline = CHAR_NL; break; case PCRE_NEWLINE_CR+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break; case PCRE_NEWLINE_ANY: newline = -1; break; case PCRE_NEWLINE_ANYCRLF: newline = -2; break; default: return PCRE_ERROR_BADNEWLINE; } if (newline == -2) { md->nltype = NLTYPE_ANYCRLF; } else if (newline < 0) { md->nltype = NLTYPE_ANY; } else { md->nltype = NLTYPE_FIXED; 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; } } /* Check a UTF-8 string if required. Unfortunately there's no way of passing back the character offset. */ #ifdef SUPPORT_UTF if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) { int erroroffset; int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset); if (errorcode != 0) { if (offsetcount >= 2) { offsets[0] = erroroffset; offsets[1] = errorcode; } return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)? PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; } if (start_offset > 0 && start_offset < length && NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) return PCRE_ERROR_BADUTF8_OFFSET; } #endif /* If the exec call supplied NULL for tables, use the inbuilt ones. This is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ if (md->tables == NULL) md->tables = PRIV(default_tables); /* The "must be at the start of a line" flags are used in a loop when finding where to start. */ startline = (re->flags & PCRE_STARTLINE) != 0; firstline = (re->options & PCRE_FIRSTLINE) != 0; /* Set up the first character to match, if available. The first_byte value is never set for an anchored regular expression, but the anchoring may be forced at run time, so we have to test for anchoring. The first char may be unset for an unanchored pattern, of course. If there's no first char and the pattern was studied, there may be a bitmap of possible first characters. */ if (!anchored) { if ((re->flags & PCRE_FIRSTSET) != 0) { has_first_char = TRUE; first_char = first_char2 = (pcre_uchar)(re->first_char); if ((re->flags & PCRE_FCH_CASELESS) != 0) { first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char); #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) if (utf && first_char > 127) first_char2 = UCD_OTHERCASE(first_char); #endif } } else { if (!startline && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) start_bits = study->start_bits; } } /* For anchored or unanchored matches, there may be a "last known required character" set. */ if ((re->flags & PCRE_REQCHSET) != 0) { has_req_char = TRUE; req_char = req_char2 = (pcre_uchar)(re->req_char); if ((re->flags & PCRE_RCH_CASELESS) != 0) { req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char); #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) if (utf && req_char > 127) req_char2 = UCD_OTHERCASE(req_char); #endif } } /* Call the main matching function, looping for a non-anchored regex after a failed match. If not restarting, perform certain optimizations at the start of a match. */ for (;;) { int rc; if ((options & PCRE_DFA_RESTART) == 0) { const pcre_uchar *save_end_subject = end_subject; /* If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. Implement this by temporarily adjusting end_subject so that we stop scanning at a newline. If the match fails at the newline, later code breaks this loop. */ if (firstline) { PCRE_PUCHAR t = current_subject; #ifdef SUPPORT_UTF if (utf) { while (t < md->end_subject && !IS_NEWLINE(t)) { t++; ACROSSCHAR(t < end_subject, *t, t++); } } else #endif while (t < md->end_subject && !IS_NEWLINE(t)) t++; end_subject = t; } /* There are some optimizations that avoid running the match if a known starting point is not found. However, there is an option that disables these, for testing and for ensuring that all callouts do actually occur. The option can be set in the regex by (*NO_START_OPT) or passed in match-time options. */ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) { /* Advance to a known first char. */ if (has_first_char) { if (first_char != first_char2) while (current_subject < end_subject && *current_subject != first_char && *current_subject != first_char2) current_subject++; else while (current_subject < end_subject && *current_subject != first_char) current_subject++; } /* Or to just after a linebreak for a multiline match if possible */ else if (startline) { if (current_subject > md->start_subject + start_offset) { #ifdef SUPPORT_UTF if (utf) { while (current_subject < end_subject && !WAS_NEWLINE(current_subject)) { current_subject++; ACROSSCHAR(current_subject < end_subject, *current_subject, current_subject++); } } else #endif while (current_subject < end_subject && !WAS_NEWLINE(current_subject)) current_subject++; /* If we have just passed a CR and the newline option is ANY or ANYCRLF, and we are now at a LF, advance the match position by one more character. */ if (current_subject[-1] == CHAR_CR && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && current_subject < end_subject && *current_subject == CHAR_NL) current_subject++; } } /* Or to a non-unique first char after study */ else if (start_bits != NULL) { while (current_subject < end_subject) { register unsigned int c = *current_subject; #ifndef COMPILE_PCRE8 if (c > 255) c = 255; #endif if ((start_bits[c/8] & (1 << (c&7))) == 0) { current_subject++; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 /* In non 8-bit mode, the iteration will stop for characters > 255 at the beginning or not stop at all. */ if (utf) ACROSSCHAR(current_subject < end_subject, *current_subject, current_subject++); #endif } else break; } } } /* Restore fudged end_subject */ end_subject = save_end_subject; /* The following two optimizations are disabled for partial matching or if disabling is explicitly requested (and of course, by the test above, this code is not obeyed when restarting after a partial match). */ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0) { /* If the pattern was studied, a minimum subject length may be set. This is a lower bound; no actual string of that length may actually match the pattern. Although the value is, strictly, in characters, we treat it as bytes to avoid spending too much time in this optimization. */ if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 && (pcre_uint32)(end_subject - current_subject) < study->minlength) return PCRE_ERROR_NOMATCH; /* If req_char is set, we know that that character must appear in the subject for the match to succeed. If the first character is set, req_char must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of work in patterns with nested unlimited repeats that aren't going to match. Writing separate code for cased/caseless versions makes it go faster, as does using an autoincrement and backing off on a match. HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary patterns. This showed up when somebody was matching /^C/ on a 32-megabyte string... so we don't do this when the string is sufficiently long. */ if (has_req_char && end_subject - current_subject < REQ_BYTE_MAX) { register PCRE_PUCHAR p = current_subject + (has_first_char? 1:0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ if (p > req_char_ptr) { if (req_char != req_char2) { while (p < end_subject) { register int pp = *p++; if (pp == req_char || pp == req_char2) { p--; break; } } } else { while (p < end_subject) { if (*p++ == req_char) { p--; break; } } } /* If we can't find the required character, break the matching loop, which will cause a return or PCRE_ERROR_NOMATCH. */ if (p >= end_subject) break; /* If we have found the required character, save the point where we found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ req_char_ptr = p; } } } } /* End of optimizations that are done when not restarting */ /* OK, now we can do the business */ md->start_used_ptr = current_subject; md->recursive = NULL; rc = internal_dfa_exec( md, /* fixed match data */ md->start_code, /* this subexpression's code */ current_subject, /* where we currently are */ start_offset, /* start offset in subject */ offsets, /* offset vector */ offsetcount, /* size of same */ workspace, /* workspace vector */ wscount, /* size of same */ 0); /* function recurse level */ /* Anything other than "no match" means we are done, always; otherwise, carry on only if not anchored. */ if (rc != PCRE_ERROR_NOMATCH || anchored) return rc; /* Advance to the next subject character unless we are at the end of a line and firstline is set. */ if (firstline && IS_NEWLINE(current_subject)) break; current_subject++; #ifdef SUPPORT_UTF if (utf) { ACROSSCHAR(current_subject < end_subject, *current_subject, current_subject++); } #endif if (current_subject > end_subject) break; /* If we have just passed a CR and we are now at a LF, and the pattern does not contain any explicit matches for \r or \n, and the newline option is CRLF or ANY or ANYCRLF, advance the match position by one more character. */ if (current_subject[-1] == CHAR_CR && current_subject < end_subject && *current_subject == CHAR_NL && (re->flags & PCRE_HASCRORLF) == 0 && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF || md->nllen == 2)) current_subject++; } /* "Bumpalong" loop */ return PCRE_ERROR_NOMATCH; } /* End of pcre_dfa_exec.c */ pcre-8.31/libpcre16.pc.in0000644000222100022210000000051311700067531012022 00000000000000# Package Information for pkg-config prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpcre16 Description: PCRE - Perl compatible regular expressions C library with 16 bit character support Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpcre16 Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ pcre-8.31/CMakeLists.txt0000644000222100022210000007135411722463274012065 00000000000000# CMakeLists.txt # # # This file allows building PCRE with the CMake configuration and build # tool. Download CMake in source or binary form from http://www.cmake.org/ # # Original listfile by Christian Ehrlicher # Refined and expanded by Daniel Richard G. # 2007-09-14 mod by Sheri so 7.4 supported configuration options can be entered # 2007-09-19 Adjusted by PH to retain previous default settings # 2007-12-26 (a) On UNIX, use names libpcre instead of just pcre # (b) Ensure pcretest and pcregrep link with the local library, # not a previously-installed one. # (c) Add PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, and # PCRE_SUPPORT_LIBBZ2. # 2008-01-20 Brought up to date to include several new features by Christian # Ehrlicher. # 2008-01-22 Sheri added options for backward compatibility of library names # when building with minGW: # if "ON", NON_STANDARD_LIB_PREFIX causes shared libraries to # be built without "lib" as prefix. (The libraries will be named # pcre.dll, pcreposix.dll and pcrecpp.dll). # if "ON", NON_STANDARD_LIB_SUFFIX causes shared libraries to # be built with suffix of "-0.dll". (The libraries will be named # libpcre-0.dll, libpcreposix-0.dll and libpcrecpp-0.dll - same names # built by default with Configure and Make. # 2008-01-23 PH removed the automatic build of pcredemo. # 2008-04-22 PH modified READLINE support so it finds NCURSES when needed. # 2008-07-03 PH updated for revised UCP property support (change of files) # 2009-03-23 PH applied Steven Van Ingelgem's patch to change the name # CMAKE_BINARY_DIR to PROJECT_BINARY_DIR so that it works when PCRE # is included within another project. # 2009-03-23 PH applied a modified version of Steven Van Ingelgem's patches to # add options to stop the building of pcregrep and the tests, and # to disable the final configuration report. # 2009-04-11 PH applied Christian Ehrlicher's patch to show compiler flags that # are set by specifying a release type. # 2010-01-02 PH added test for stdint.h # 2010-03-02 PH added test for inttypes.h # 2011-08-01 PH added PCREGREP_BUFSIZE # 2011-08-22 PH added PCRE_SUPPORT_JIT # 2011-09-06 PH modified WIN32 ADD_TEST line as suggested by Sergey Cherepanov # 2011-09-06 PH added PCRE_SUPPORT_PCREGREP_JIT # 2011-10-04 Sheri added support for including coff data in windows shared libraries # compiled with MINGW if pcre.rc and/or pcreposix.rc are placed in # the source dir by the user prior to building # 2011-10-04 Sheri changed various add_test's to use exes' location built instead # of DEBUG location only (likely only matters in MSVC) # 2011-10-04 Sheri added scripts to provide needed variables to RunTest and # RunGrepTest (used for UNIX and Msys) # 2011-10-04 Sheri added scripts to provide needed variables and to execute # RunTest.bat in Win32 (for effortless testing with "make test") # 2011-10-04 Sheri Increased minimum required cmake version # 2012-01-06 PH removed pcre_info.c and added pcre_string_utils.c # 2012-01-10 Zoltan Herczeg added libpcre16 support # 2012-01-13 Stephen Kelly added out of source build support # 2012-01-17 PH applied Stephen Kelly's patch to parse the version data out # of the configure.ac file # 2012-02-26 PH added support for libedit PROJECT(PCRE C CXX) # Increased minimum to 2.8.0 to support newer add_test features CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # for FindReadline.cmake # external packages FIND_PACKAGE( BZip2 ) FIND_PACKAGE( ZLIB ) FIND_PACKAGE( Readline ) FIND_PACKAGE( Editline ) # Configuration checks INCLUDE(CheckIncludeFile) INCLUDE(CheckIncludeFileCXX) INCLUDE(CheckFunctionExists) INCLUDE(CheckTypeSize) CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H) CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H) CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H) CHECK_INCLUDE_FILE_CXX(type_traits.h HAVE_TYPE_TRAITS_H) CHECK_INCLUDE_FILE_CXX(bits/type_traits.h HAVE_BITS_TYPE_TRAITS_H) CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY) CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL) CHECK_FUNCTION_EXISTS(strtoq HAVE_STRTOQ) CHECK_FUNCTION_EXISTS(_strtoi64 HAVE__STRTOI64) CHECK_TYPE_SIZE("long long" LONG_LONG) CHECK_TYPE_SIZE("unsigned long long" UNSIGNED_LONG_LONG) # User-configurable options # # (Note: CMakeSetup displays these in alphabetical order, regardless of # the order we use here) SET(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries instead of static ones.") OPTION(PCRE_BUILD_PCRE8 "Build 8 bit PCRE library" ON) OPTION(PCRE_BUILD_PCRE16 "Build 16 bit PCRE library" OFF) OPTION(PCRE_BUILD_PCRECPP "Build the PCRE C++ library (pcrecpp)." ON) SET(PCRE_EBCDIC OFF CACHE BOOL "Use EBCDIC coding instead of ASCII. (This is rarely used outside of mainframe systems)") SET(PCRE_LINK_SIZE "2" CACHE STRING "Internal link size (2, 3 or 4 allowed). See LINK_SIZE in config.h.in for details.") SET(PCRE_MATCH_LIMIT "10000000" CACHE STRING "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.") SET(PCRE_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING "Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.") SET(PCREGREP_BUFSIZE "20480" CACHE STRING "Buffer size parameter for pcregrep. See PCREGREP_BUFSIZE in config.h.in for details.") SET(PCRE_NEWLINE "LF" CACHE STRING "What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF).") SET(PCRE_NO_RECURSE OFF CACHE BOOL "If ON, then don't use stack recursion when matching. See NO_RECURSE in config.h.in for details.") SET(PCRE_POSIX_MALLOC_THRESHOLD "10" CACHE STRING "Threshold for malloc() usage. See POSIX_MALLOC_THRESHOLD in config.h.in for details.") SET(PCRE_SUPPORT_JIT OFF CACHE BOOL "Enable support for Just-in-time compiling.") SET(PCRE_SUPPORT_PCREGREP_JIT ON CACHE BOOL "Enable use of Just-in-time compiling in pcregrep.") SET(PCRE_SUPPORT_UTF OFF CACHE BOOL "Enable support for Unicode Transformation Format (UTF-8 and/or UTF-16) encoding.") SET(PCRE_SUPPORT_UNICODE_PROPERTIES OFF CACHE BOOL "Enable support for Unicode properties (if set, UTF support will be enabled as well).") SET(PCRE_SUPPORT_BSR_ANYCRLF OFF CACHE BOOL "ON=Backslash-R matches only LF CR and CRLF, OFF=Backslash-R matches all Unicode Linebreaks") OPTION(PCRE_SHOW_REPORT "Show the final configuration report" ON) OPTION(PCRE_BUILD_PCREGREP "Build pcregrep" ON) OPTION(PCRE_BUILD_TESTS "Build the tests" ON) IF (MINGW) OPTION(NON_STANDARD_LIB_PREFIX "ON=Shared libraries built in mingw will be named pcre.dll, etc., instead of libpcre.dll, etc." OFF) OPTION(NON_STANDARD_LIB_SUFFIX "ON=Shared libraries built in mingw will be named libpcre-0.dll, etc., instead of libpcre.dll, etc." OFF) ENDIF(MINGW) # bzip2 lib IF(BZIP2_FOUND) OPTION (PCRE_SUPPORT_LIBBZ2 "Enable support for linking pcregrep with libbz2." ON) ENDIF(BZIP2_FOUND) IF(PCRE_SUPPORT_LIBBZ2) INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR}) ENDIF(PCRE_SUPPORT_LIBBZ2) # zlib IF(ZLIB_FOUND) OPTION (PCRE_SUPPORT_LIBZ "Enable support for linking pcregrep with libz." ON) ENDIF(ZLIB_FOUND) IF(PCRE_SUPPORT_LIBZ) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) ENDIF(PCRE_SUPPORT_LIBZ) # editline lib IF(EDITLINE_FOUND) OPTION (PCRE_SUPPORT_LIBEDIT "Enable support for linking pcretest with libedit." OFF) ENDIF(EDITLINE_FOUND) IF(PCRE_SUPPORT_LIBEDIT) INCLUDE_DIRECTORIES(${EDITLINE_INCLUDE_DIR}) ENDIF(PCRE_SUPPORT_LIBEDIT) # readline lib IF(READLINE_FOUND) OPTION (PCRE_SUPPORT_LIBREADLINE "Enable support for linking pcretest with libreadline." ON) ENDIF(READLINE_FOUND) IF(PCRE_SUPPORT_LIBREADLINE) INCLUDE_DIRECTORIES(${READLINE_INCLUDE_DIR}) ENDIF(PCRE_SUPPORT_LIBREADLINE) # Prepare build configuration SET(pcre_have_type_traits 0) SET(pcre_have_bits_type_traits 0) IF(HAVE_TYPE_TRAITS_H) SET(pcre_have_type_traits 1) ENDIF(HAVE_TYPE_TRAITS_H) IF(HAVE_BITS_TYPE_TRAITS_H) SET(pcre_have_bits_type_traits 1) ENDIF(HAVE_BITS_TYPE_TRAITS_H) SET(pcre_have_long_long 0) SET(pcre_have_ulong_long 0) IF(HAVE_LONG_LONG) SET(pcre_have_long_long 1) ENDIF(HAVE_LONG_LONG) IF(HAVE_UNSIGNED_LONG_LONG) SET(pcre_have_ulong_long 1) ENDIF(HAVE_UNSIGNED_LONG_LONG) IF(NOT BUILD_SHARED_LIBS) SET(PCRE_STATIC 1) ENDIF(NOT BUILD_SHARED_LIBS) IF(NOT PCRE_BUILD_PCRE8 AND NOT PCRE_BUILD_PCRE16) MESSAGE(FATAL_ERROR "Either PCRE_BUILD_PCRE8 or PCRE_BUILD_PCRE16 must be enabled") ENDIF(NOT PCRE_BUILD_PCRE8 AND NOT PCRE_BUILD_PCRE16) IF(PCRE_BUILD_PCRE8) SET(SUPPORT_PCRE8 1) ENDIF(PCRE_BUILD_PCRE8) IF(PCRE_BUILD_PCRE16) SET(SUPPORT_PCRE16 1) ENDIF(PCRE_BUILD_PCRE16) IF(PCRE_BUILD_PCRECPP AND NOT PCRE_BUILD_PCRE8) MESSAGE(STATUS "** PCRE_BUILD_PCRE8 must be enabled for the C++ library support") SET(PCRE_BUILD_PCRECPP OFF) ENDIF(PCRE_BUILD_PCRECPP AND NOT PCRE_BUILD_PCRE8) IF(PCRE_BUILD_PCREGREP AND NOT PCRE_BUILD_PCRE8) MESSAGE(STATUS "** PCRE_BUILD_PCRE8 must be enabled for the pcregrep program") SET(PCRE_BUILD_PCREGREP OFF) ENDIF(PCRE_BUILD_PCREGREP AND NOT PCRE_BUILD_PCRE8) IF(PCRE_SUPPORT_LIBREADLINE AND PCRE_SUPPORT_LIBEDIT) MESSAGE(FATAL_ERROR "Only one of libreadline or libeditline can be specified") ENDIF(PCRE_SUPPORT_LIBREADLINE AND PCRE_SUPPORT_LIBEDIT) IF(PCRE_SUPPORT_BSR_ANYCRLF) SET(BSR_ANYCRLF 1) ENDIF(PCRE_SUPPORT_BSR_ANYCRLF) IF(PCRE_SUPPORT_UTF OR PCRE_SUPPORT_UNICODE_PROPERTIES) SET(SUPPORT_UTF 1) SET(PCRE_SUPPORT_UTF ON) ENDIF(PCRE_SUPPORT_UTF OR PCRE_SUPPORT_UNICODE_PROPERTIES) IF(PCRE_SUPPORT_UNICODE_PROPERTIES) SET(SUPPORT_UCP 1) ENDIF(PCRE_SUPPORT_UNICODE_PROPERTIES) IF(PCRE_SUPPORT_JIT) SET(SUPPORT_JIT 1) ENDIF(PCRE_SUPPORT_JIT) IF(PCRE_SUPPORT_PCREGREP_JIT) SET(SUPPORT_PCREGREP_JIT 1) ENDIF(PCRE_SUPPORT_PCREGREP_JIT) # This next one used to contain # SET(PCRETEST_LIBS ${READLINE_LIBRARY}) # but I was advised to add the NCURSES test as well, along with # some modifications to cmake/FindReadline.cmake which should # make it possible to override the default if necessary. PH IF(PCRE_SUPPORT_LIBREADLINE) SET(SUPPORT_LIBREADLINE 1) SET(PCRETEST_LIBS ${READLINE_LIBRARY} ${NCURSES_LIBRARY}) ENDIF(PCRE_SUPPORT_LIBREADLINE) # libedit is a plug-compatible alternative to libreadline IF(PCRE_SUPPORT_LIBEDIT) SET(SUPPORT_LIBEDIT 1) SET(PCRETEST_LIBS ${EDITLINE_LIBRARY} ${NCURSES_LIBRARY}) ENDIF(PCRE_SUPPORT_LIBEDIT) IF(PCRE_SUPPORT_LIBZ) SET(SUPPORT_LIBZ 1) SET(PCREGREP_LIBS ${PCREGREP_LIBS} ${ZLIB_LIBRARIES}) ENDIF(PCRE_SUPPORT_LIBZ) IF(PCRE_SUPPORT_LIBBZ2) SET(SUPPORT_LIBBZ2 1) SET(PCREGREP_LIBS ${PCREGREP_LIBS} ${BZIP2_LIBRARIES}) ENDIF(PCRE_SUPPORT_LIBBZ2) SET(NEWLINE "") IF(PCRE_NEWLINE STREQUAL "LF") SET(NEWLINE "10") ENDIF(PCRE_NEWLINE STREQUAL "LF") IF(PCRE_NEWLINE STREQUAL "CR") SET(NEWLINE "13") ENDIF(PCRE_NEWLINE STREQUAL "CR") IF(PCRE_NEWLINE STREQUAL "CRLF") SET(NEWLINE "3338") ENDIF(PCRE_NEWLINE STREQUAL "CRLF") IF(PCRE_NEWLINE STREQUAL "ANY") SET(NEWLINE "-1") ENDIF(PCRE_NEWLINE STREQUAL "ANY") IF(PCRE_NEWLINE STREQUAL "ANYCRLF") SET(NEWLINE "-2") ENDIF(PCRE_NEWLINE STREQUAL "ANYCRLF") IF(NEWLINE STREQUAL "") MESSAGE(FATAL_ERROR "The PCRE_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".") ENDIF(NEWLINE STREQUAL "") IF(PCRE_EBCDIC) SET(EBCDIC 1) ENDIF(PCRE_EBCDIC) IF(PCRE_NO_RECURSE) SET(NO_RECURSE 1) ENDIF(PCRE_NO_RECURSE) # Output files CONFIGURE_FILE(config-cmake.h.in ${PROJECT_BINARY_DIR}/config.h @ONLY) # Parse version numbers and date out of configure.ac file(STRINGS ${PROJECT_SOURCE_DIR}/configure.ac configure_lines LIMIT_COUNT 50 # Read only the first 50 lines of the file ) set(SEARCHED_VARIABLES "pcre_major" "pcre_minor" "pcre_prerelease" "pcre_date") foreach(configure_line ${configure_lines}) foreach(_substitution_variable ${SEARCHED_VARIABLES}) string(TOUPPER ${_substitution_variable} _substitution_variable_upper) if (NOT ${_substitution_variable_upper}) string(REGEX MATCH "m4_define\\(${_substitution_variable}, \\[(.*)\\]" MACTHED_STRING ${configure_line}) if (CMAKE_MATCH_1) set(${_substitution_variable_upper} ${CMAKE_MATCH_1}) endif() endif() endforeach() endforeach() CONFIGURE_FILE(pcre.h.in ${PROJECT_BINARY_DIR}/pcre.h @ONLY) # What about pcre-config and libpcre.pc? IF(PCRE_BUILD_PCRECPP) CONFIGURE_FILE(pcre_stringpiece.h.in ${PROJECT_BINARY_DIR}/pcre_stringpiece.h @ONLY) CONFIGURE_FILE(pcrecpparg.h.in ${PROJECT_BINARY_DIR}/pcrecpparg.h @ONLY) ENDIF(PCRE_BUILD_PCRECPP) # Character table generation OPTION(PCRE_REBUILD_CHARTABLES "Rebuild char tables" OFF) IF(PCRE_REBUILD_CHARTABLES) ADD_EXECUTABLE(dftables dftables.c) GET_TARGET_PROPERTY(DFTABLES_EXE dftables LOCATION) ADD_CUSTOM_COMMAND( COMMENT "Generating character tables (pcre_chartables.c) for current locale" DEPENDS dftables COMMAND ${DFTABLES_EXE} ARGS ${PROJECT_BINARY_DIR}/pcre_chartables.c OUTPUT ${PROJECT_BINARY_DIR}/pcre_chartables.c ) ELSE(PCRE_REBUILD_CHARTABLES) CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/pcre_chartables.c.dist ${PROJECT_BINARY_DIR}/pcre_chartables.c COPYONLY) ENDIF(PCRE_REBUILD_CHARTABLES) # Source code SET(PCRE_HEADERS ${PROJECT_BINARY_DIR}/pcre.h) IF(PCRE_BUILD_PCRE8) SET(PCRE_SOURCES pcre_byte_order.c pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_jit_compile.c pcre_maketables.c pcre_newline.c pcre_ord2utf8.c pcre_refcount.c pcre_string_utils.c pcre_study.c pcre_tables.c pcre_ucd.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c ) SET(PCREPOSIX_HEADERS pcreposix.h) SET(PCREPOSIX_SOURCES pcreposix.c) ENDIF(PCRE_BUILD_PCRE8) IF(PCRE_BUILD_PCRE16) SET(PCRE16_SOURCES pcre16_byte_order.c pcre16_chartables.c pcre16_compile.c pcre16_config.c pcre16_dfa_exec.c pcre16_exec.c pcre16_fullinfo.c pcre16_get.c pcre16_globals.c pcre16_jit_compile.c pcre16_maketables.c pcre16_newline.c pcre16_ord2utf16.c pcre16_refcount.c pcre16_string_utils.c pcre16_study.c pcre16_tables.c pcre16_ucd.c pcre16_utf16_utils.c pcre16_valid_utf16.c pcre16_version.c pcre16_xclass.c ) ENDIF(PCRE_BUILD_PCRE16) IF(MINGW AND NOT PCRE_STATIC) IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre.rc) ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcre.o PRE-LINK COMMAND windres ARGS pcre.rc pcre.o WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMENT Using pcre coff info in mingw build) SET(PCRE_SOURCES ${PCRE_SOURCES} ${PROJECT_SOURCE_DIR}/pcre.o ) ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre.rc) IF (EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcreposix.o PRE-LINK COMMAND windres ARGS pcreposix.rc pcreposix.o WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMENT Using pcreposix coff info in mingw build) SET(PCREPOSIX_SOURCES ${PCREPOSIX_SOURCES} ${PROJECT_SOURCE_DIR}/pcreposix.o ) ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) ENDIF(MINGW AND NOT PCRE_STATIC) SET(PCRECPP_HEADERS pcrecpp.h pcre_scanner.h ${PROJECT_BINARY_DIR}/pcrecpparg.h ${PROJECT_BINARY_DIR}/pcre_stringpiece.h ) SET(PCRECPP_SOURCES pcrecpp.cc pcre_scanner.cc pcre_stringpiece.cc ) # Build setup ADD_DEFINITIONS(-DHAVE_CONFIG_H) IF(MSVC) ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) ENDIF(MSVC) SET(CMAKE_INCLUDE_CURRENT_DIR 1) # needed to make sure to not link debug libs # against release libs and vice versa IF(WIN32) SET(CMAKE_DEBUG_POSTFIX "d") ENDIF(WIN32) SET(targets) # Libraries # pcre IF(PCRE_BUILD_PCRE8) ADD_LIBRARY(pcre ${PCRE_HEADERS} ${PCRE_SOURCES} ${PROJECT_BINARY_DIR}/config.h) SET(targets ${targets} pcre) ADD_LIBRARY(pcreposix ${PCREPOSIX_HEADERS} ${PCREPOSIX_SOURCES}) SET(targets ${targets} pcreposix) TARGET_LINK_LIBRARIES(pcreposix pcre) IF(MINGW AND NOT PCRE_STATIC) IF(NON_STANDARD_LIB_PREFIX) SET_TARGET_PROPERTIES(pcre pcreposix PROPERTIES PREFIX "" ) ENDIF(NON_STANDARD_LIB_PREFIX) IF(NON_STANDARD_LIB_SUFFIX) SET_TARGET_PROPERTIES(pcre pcreposix PROPERTIES SUFFIX "-0.dll" ) ENDIF(NON_STANDARD_LIB_SUFFIX) ENDIF(MINGW AND NOT PCRE_STATIC) ENDIF(PCRE_BUILD_PCRE8) IF(PCRE_BUILD_PCRE16) ADD_LIBRARY(pcre16 ${PCRE_HEADERS} ${PCRE16_SOURCES} ${PROJECT_BINARY_DIR}/config.h) SET(targets ${targets} pcre16) IF(MINGW AND NOT PCRE_STATIC) IF(NON_STANDARD_LIB_PREFIX) SET_TARGET_PROPERTIES(pcre16 PROPERTIES PREFIX "" ) ENDIF(NON_STANDARD_LIB_PREFIX) IF(NON_STANDARD_LIB_SUFFIX) SET_TARGET_PROPERTIES(pcre16 PROPERTIES SUFFIX "-0.dll" ) ENDIF(NON_STANDARD_LIB_SUFFIX) ENDIF(MINGW AND NOT PCRE_STATIC) ENDIF(PCRE_BUILD_PCRE16) # pcrecpp IF(PCRE_BUILD_PCRECPP) ADD_LIBRARY(pcrecpp ${PCRECPP_HEADERS} ${PCRECPP_SOURCES}) SET(targets ${targets} pcrecpp) TARGET_LINK_LIBRARIES(pcrecpp pcre) IF(MINGW AND NOT PCRE_STATIC) IF(NON_STANDARD_LIB_PREFIX) SET_TARGET_PROPERTIES(pcrecpp PROPERTIES PREFIX "" ) ENDIF(NON_STANDARD_LIB_PREFIX) IF(NON_STANDARD_LIB_SUFFIX) SET_TARGET_PROPERTIES(pcrecpp PROPERTIES SUFFIX "-0.dll" ) ENDIF(NON_STANDARD_LIB_SUFFIX) ENDIF(MINGW AND NOT PCRE_STATIC) ENDIF(PCRE_BUILD_PCRECPP) # Executables # Removed by PH (2008-01-23) because pcredemo shouldn't really be built # automatically, and it gave trouble in some environments anyway. # ADD_EXECUTABLE(pcredemo pcredemo.c) # TARGET_LINK_LIBRARIES(pcredemo pcreposix) # IF(NOT BUILD_SHARED_LIBS) # # make sure to not use declspec(dllimport) in static mode on windows # SET_TARGET_PROPERTIES(pcredemo PROPERTIES COMPILE_FLAGS "-DPCRE_STATIC") # ENDIF(NOT BUILD_SHARED_LIBS) IF(PCRE_BUILD_PCREGREP) ADD_EXECUTABLE(pcregrep pcregrep.c) SET(targets ${targets} pcregrep) TARGET_LINK_LIBRARIES(pcregrep pcreposix ${PCREGREP_LIBS}) ENDIF(PCRE_BUILD_PCREGREP) # Testing IF(PCRE_BUILD_TESTS) ENABLE_TESTING() SET(PCRETEST_SOURCES pcretest.c) IF(PCRE_BUILD_PCRE8) LIST(APPEND PCRETEST_SOURCES pcre_printint.c) ENDIF(PCRE_BUILD_PCRE8) IF(PCRE_BUILD_PCRE16) LIST(APPEND PCRETEST_SOURCES pcre16_printint.c) ENDIF(PCRE_BUILD_PCRE16) ADD_EXECUTABLE(pcretest ${PCRETEST_SOURCES}) SET(targets ${targets} pcretest) IF(PCRE_BUILD_PCRE8) LIST(APPEND PCRETEST_LIBS pcreposix pcre) ENDIF(PCRE_BUILD_PCRE8) IF(PCRE_BUILD_PCRE16) LIST(APPEND PCRETEST_LIBS pcre16) ENDIF(PCRE_BUILD_PCRE16) TARGET_LINK_LIBRARIES(pcretest ${PCRETEST_LIBS}) IF(PCRE_SUPPORT_JIT) ADD_EXECUTABLE(pcre_jit_test pcre_jit_test.c) SET(targets ${targets} pcre_jit_test) SET(PCRE_JIT_TEST_LIBS ) IF(PCRE_BUILD_PCRE8) LIST(APPEND PCRE_JIT_TEST_LIBS pcre) ENDIF(PCRE_BUILD_PCRE8) IF(PCRE_BUILD_PCRE16) LIST(APPEND PCRE_JIT_TEST_LIBS pcre16) ENDIF(PCRE_BUILD_PCRE16) TARGET_LINK_LIBRARIES(pcre_jit_test ${PCRE_JIT_TEST_LIBS}) ENDIF(PCRE_SUPPORT_JIT) IF(PCRE_BUILD_PCRECPP) ADD_EXECUTABLE(pcrecpp_unittest pcrecpp_unittest.cc) SET(targets ${targets} pcrecpp_unittest) TARGET_LINK_LIBRARIES(pcrecpp_unittest pcrecpp) IF(MINGW AND NON_STANDARD_LIB_NAMES AND NOT PCRE_STATIC) SET_TARGET_PROPERTIES(pcrecpp PROPERTIES PREFIX "" ) ENDIF(MINGW AND NON_STANDARD_LIB_NAMES AND NOT PCRE_STATIC) ADD_EXECUTABLE(pcre_scanner_unittest pcre_scanner_unittest.cc) SET(targets ${targets} pcre_scanner_unittest) TARGET_LINK_LIBRARIES(pcre_scanner_unittest pcrecpp) ADD_EXECUTABLE(pcre_stringpiece_unittest pcre_stringpiece_unittest.cc) SET(targets ${targets} pcre_stringpiece_unittest) TARGET_LINK_LIBRARIES(pcre_stringpiece_unittest pcrecpp) ENDIF(PCRE_BUILD_PCRECPP) # exes in Debug location tested by the RunTest shell script # via "make test" IF(PCRE_BUILD_PCREGREP) GET_TARGET_PROPERTY(PCREGREP_EXE pcregrep DEBUG_LOCATION) ENDIF(PCRE_BUILD_PCREGREP) GET_TARGET_PROPERTY(PCRETEST_EXE pcretest DEBUG_LOCATION) # ================================================= # Write out a CTest configuration file # FILE(WRITE ${PROJECT_BINARY_DIR}/CTestCustom.ctest "# This is a generated file. MESSAGE(\"When testing is complete, review test output in the ${PROJECT_BINARY_DIR}/Testing/Temporary folder.\") MESSAGE(\"\") ") FILE(WRITE ${PROJECT_BINARY_DIR}/pcre_test.sh "#! /bin/sh # This is a generated file. srcdir=${PROJECT_SOURCE_DIR} pcretest=${PCRETEST_EXE} source ${PROJECT_SOURCE_DIR}/RunTest if test \"$?\" != \"0\"; then exit 1; fi # End ") IF(UNIX) ADD_TEST(pcre_test sh ${PROJECT_BINARY_DIR}/pcre_test.sh) ENDIF(UNIX) IF(PCRE_BUILD_PCREGREP) FILE(WRITE ${PROJECT_BINARY_DIR}/pcre_grep_test.sh "#! /bin/sh # This is a generated file. srcdir=${PROJECT_SOURCE_DIR} pcregrep=${PCREGREP_EXE} pcretest=${PCRETEST_EXE} source ${PROJECT_SOURCE_DIR}/RunGrepTest if test \"$?\" != \"0\"; then exit 1; fi # End ") IF(UNIX) ADD_TEST(pcre_grep_test sh ${PROJECT_BINARY_DIR}/pcre_grep_test.sh) ENDIF(UNIX) ENDIF(PCRE_BUILD_PCREGREP) IF(WIN32) # Provide environment for executing the bat file version of RunTest string(REPLACE "/" "\\" winsrc "${PROJECT_SOURCE_DIR}") FILE(WRITE ${PROJECT_BINARY_DIR}/pcre_test.txt "\@REM This is a generated file. \@Echo off setlocal SET\ srcdir=\${srcdir} SET\ pcretest=\${pcretest} call \"\${srcdir}\\RunTest.Bat\" if errorlevel 1 exit /b 1 echo RunTest.bat tests successfully completed ") FILE(WRITE ${PROJECT_BINARY_DIR}/BatDriver.cmake "# This is a generated file. # this script is run with arguments via the cmake command in add_test(NAME pcre_test_bat) # BatDriver feeds the actual location of pcretest.exe FILE(TO_NATIVE_PATH \${pcretestx} pcretest) FILE(TO_NATIVE_PATH \${srcdirx} srcdir) configure_file(\"\${bindirx}/pcre_test.txt\" \"\${bindirx}/pcre_test.bat\") # MESSAGE(\"cmake\ variable\ pcretest\ is\ \${pcretest}\") # STRING(REPLACE \" \" \"\\ \" bindir \${bindirx}) MESSAGE(\"COMMAND pcre_test.bat \") EXECUTE_PROCESS(COMMAND pcre_test.bat WORKING_DIRECTORY . OUTPUT_VARIABLE batoutput) MESSAGE(\"OUTPUT: \${batoutput}\") ") ADD_TEST(NAME pcre_test_bat COMMAND ${CMAKE_COMMAND} -D bindirx=${PROJECT_BINARY_DIR} -D srcdirx=${PROJECT_SOURCE_DIR} -D pcretestx=$ -P "${PROJECT_BINARY_DIR}/BatDriver.cmake") SET_TESTS_PROPERTIES(pcre_test_bat PROPERTIES PASS_REGULAR_EXPRESSION "RunTest\\.bat tests successfully completed") IF("$ENV{OSTYPE}" STREQUAL "msys") # Both the sh and bat file versions of RunTest are run if make test is used # in msys ADD_TEST(pcre_test_sh sh.exe ${PROJECT_BINARY_DIR}/pcre_test.sh) IF(PCRE_BUILD_PCREGREP) ADD_TEST(pcre_grep_test sh.exe ${PROJECT_BINARY_DIR}/pcre_grep_test.sh) ENDIF(PCRE_BUILD_PCREGREP) ENDIF("$ENV{OSTYPE}" STREQUAL "msys") ENDIF(WIN32) # Changed to accommodate testing whichever location was just built IF(PCRE_SUPPORT_JIT) ADD_TEST(pcre_jit_test pcre_jit_test) ENDIF(PCRE_SUPPORT_JIT) IF(PCRE_BUILD_PCRECPP) ADD_TEST(pcrecpp_test pcrecpp_unittest) ADD_TEST(pcre_scanner_test pcre_scanner_unittest) ADD_TEST(pcre_stringpiece_test pcre_stringpiece_unittest) ENDIF(PCRE_BUILD_PCRECPP) ENDIF(PCRE_BUILD_TESTS) # Installation SET(CMAKE_INSTALL_ALWAYS 1) INSTALL(TARGETS ${targets} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) INSTALL(FILES ${PCRE_HEADERS} ${PCREPOSIX_HEADERS} DESTINATION include) FILE(GLOB html ${PROJECT_SOURCE_DIR}/doc/html/*.html) FILE(GLOB man1 ${PROJECT_SOURCE_DIR}/doc/*.1) FILE(GLOB man3 ${PROJECT_SOURCE_DIR}/doc/*.3) IF(PCRE_BUILD_PCRECPP) INSTALL(FILES ${PCRECPP_HEADERS} DESTINATION include) ELSE(PCRE_BUILD_PCRECPP) # Remove pcrecpp.3 FOREACH(man ${man3}) GET_FILENAME_COMPONENT(man_tmp ${man} NAME) IF(NOT man_tmp STREQUAL "pcrecpp.3") SET(man3_new ${man3} ${man}) ENDIF(NOT man_tmp STREQUAL "pcrecpp.3") ENDFOREACH(man ${man3}) SET(man3 ${man3_new}) ENDIF(PCRE_BUILD_PCRECPP) INSTALL(FILES ${man1} DESTINATION man/man1) INSTALL(FILES ${man3} DESTINATION man/man3) INSTALL(FILES ${html} DESTINATION share/doc/pcre/html) # help, only for nice output IF(BUILD_SHARED_LIBS) SET(BUILD_STATIC_LIBS OFF) ELSE(BUILD_SHARED_LIBS) SET(BUILD_STATIC_LIBS ON) ENDIF(BUILD_SHARED_LIBS) IF(PCRE_SHOW_REPORT) STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype) IF (CMAKE_C_FLAGS) SET(cfsp " ") ENDIF(CMAKE_C_FLAGS) IF (CMAKE_CXX_FLAGS) SET(cxxfsp " ") ENDIF(CMAKE_CXX_FLAGS) MESSAGE(STATUS "") MESSAGE(STATUS "") MESSAGE(STATUS "PCRE configuration summary:") MESSAGE(STATUS "") MESSAGE(STATUS " Install prefix .................. : ${CMAKE_INSTALL_PREFIX}") MESSAGE(STATUS " C compiler ...................... : ${CMAKE_C_COMPILER}") MESSAGE(STATUS " C++ compiler .................... : ${CMAKE_CXX_COMPILER}") MESSAGE(STATUS " C compiler flags ................ : ${CMAKE_C_FLAGS}${cfsp}${CMAKE_C_FLAGS_${buildtype}}") MESSAGE(STATUS " C++ compiler flags .............. : ${CMAKE_CXX_FLAGS}${cxxfsp}${CMAKE_CXX_FLAGS_${buildtype}}") MESSAGE(STATUS "") MESSAGE(STATUS " Build 8 bit PCRE library ........ : ${PCRE_BUILD_PCRE8}") MESSAGE(STATUS " Build 16 bit PCRE library ....... : ${PCRE_BUILD_PCRE16}") MESSAGE(STATUS " Build C++ library ............... : ${PCRE_BUILD_PCRECPP}") MESSAGE(STATUS " Enable JIT compiling support .... : ${PCRE_SUPPORT_JIT}") MESSAGE(STATUS " Enable UTF support .............. : ${PCRE_SUPPORT_UTF}") MESSAGE(STATUS " Unicode properties .............. : ${PCRE_SUPPORT_UNICODE_PROPERTIES}") MESSAGE(STATUS " Newline char/sequence ........... : ${PCRE_NEWLINE}") MESSAGE(STATUS " \\R matches only ANYCRLF ......... : ${PCRE_SUPPORT_BSR_ANYCRLF}") MESSAGE(STATUS " EBCDIC coding ................... : ${PCRE_EBCDIC}") MESSAGE(STATUS " Rebuild char tables ............. : ${PCRE_REBUILD_CHARTABLES}") MESSAGE(STATUS " No stack recursion .............. : ${PCRE_NO_RECURSE}") MESSAGE(STATUS " POSIX mem threshold ............. : ${PCRE_POSIX_MALLOC_THRESHOLD}") MESSAGE(STATUS " Internal link size .............. : ${PCRE_LINK_SIZE}") MESSAGE(STATUS " Match limit ..................... : ${PCRE_MATCH_LIMIT}") MESSAGE(STATUS " Match limit recursion ........... : ${PCRE_MATCH_LIMIT_RECURSION}") MESSAGE(STATUS " Build shared libs ............... : ${BUILD_SHARED_LIBS}") MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}") MESSAGE(STATUS " Build pcregrep .................. : ${PCRE_BUILD_PCREGREP}") MESSAGE(STATUS " Enable JIT in pcregrep .......... : ${PCRE_SUPPORT_PCREGREP_JIT}") MESSAGE(STATUS " Buffer size for pcregrep ........ : ${PCREGREP_BUFSIZE}") MESSAGE(STATUS " Build tests (implies pcretest .. : ${PCRE_BUILD_TESTS}") MESSAGE(STATUS " and pcregrep)") IF(ZLIB_FOUND) MESSAGE(STATUS " Link pcregrep with libz ......... : ${PCRE_SUPPORT_LIBZ}") ELSE(ZLIB_FOUND) MESSAGE(STATUS " Link pcregrep with libz ......... : Library not found" ) ENDIF(ZLIB_FOUND) IF(BZIP2_FOUND) MESSAGE(STATUS " Link pcregrep with libbz2 ....... : ${PCRE_SUPPORT_LIBBZ2}") ELSE(BZIP2_FOUND) MESSAGE(STATUS " Link pcregrep with libbz2 ....... : Library not found" ) ENDIF(BZIP2_FOUND) IF(EDITLINE_FOUND) MESSAGE(STATUS " Link pcretest with libeditline .. : ${PCRE_SUPPORT_LIBEDIT}") ELSE(EDITLINE_FOUND) MESSAGE(STATUS " Link pcretest with libeditline .. : Library not found" ) ENDIF(EDITLINE_FOUND) IF(READLINE_FOUND) MESSAGE(STATUS " Link pcretest with libreadline .. : ${PCRE_SUPPORT_LIBREADLINE}") ELSE(READLINE_FOUND) MESSAGE(STATUS " Link pcretest with libreadline .. : Library not found" ) ENDIF(READLINE_FOUND) IF(MINGW AND NOT PCRE_STATIC) MESSAGE(STATUS " Non-standard dll names (prefix) . : ${NON_STANDARD_LIB_PREFIX}") MESSAGE(STATUS " Non-standard dll names (suffix) . : ${NON_STANDARD_LIB_SUFFIX}") ENDIF(MINGW AND NOT PCRE_STATIC) MESSAGE(STATUS "") ENDIF(PCRE_SHOW_REPORT) # end CMakeLists.txt pcre-8.31/pcre_newline.c0000644000222100022210000001420611676645226012143 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains internal functions for testing newlines when more than one kind of newline is to be recognized. When a newline is found, its length is returned. In principle, we could implement several newline "types", each referring to a different set of newline characters. At present, PCRE supports only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF, and NLTYPE_ANY. The full list of Unicode newline characters is taken from http://unicode.org/unicode/reports/tr18/. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Check for newline at given position * *************************************************/ /* It is guaranteed that the initial value of ptr is less than the end of the string that is being processed. Arguments: ptr pointer to possible newline type the newline type endptr pointer to the end of the string lenptr where to return the length utf TRUE if in utf mode Returns: TRUE or FALSE */ BOOL PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr, BOOL utf) { int c; (void)utf; #ifdef SUPPORT_UTF if (utf) { GETCHAR(c, ptr); } else #endif /* SUPPORT_UTF */ c = *ptr; if (type == NLTYPE_ANYCRLF) switch(c) { case 0x000a: *lenptr = 1; return TRUE; /* LF */ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; return TRUE; /* CR */ default: return FALSE; } /* NLTYPE_ANY */ else switch(c) { case 0x000a: /* LF */ case 0x000b: /* VT */ case 0x000c: *lenptr = 1; return TRUE; /* FF */ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; return TRUE; /* CR */ #ifdef COMPILE_PCRE8 case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ #else case 0x0085: /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 1; return TRUE; /* PS */ #endif /* COMPILE_PCRE8 */ default: return FALSE; } } /************************************************* * Check for newline at previous position * *************************************************/ /* It is guaranteed that the initial value of ptr is greater than the start of the string that is being processed. Arguments: ptr pointer to possible newline type the newline type startptr pointer to the start of the string lenptr where to return the length utf TRUE if in utf mode Returns: TRUE or FALSE */ BOOL PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr, BOOL utf) { int c; (void)utf; ptr--; #ifdef SUPPORT_UTF if (utf) { BACKCHAR(ptr); GETCHAR(c, ptr); } else #endif /* SUPPORT_UTF */ c = *ptr; if (type == NLTYPE_ANYCRLF) switch(c) { case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1; return TRUE; /* LF */ case 0x000d: *lenptr = 1; return TRUE; /* CR */ default: return FALSE; } else switch(c) { case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1; return TRUE; /* LF */ case 0x000b: /* VT */ case 0x000c: /* FF */ case 0x000d: *lenptr = 1; return TRUE; /* CR */ #ifdef COMPILE_PCRE8 case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ #else case 0x0085: /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 1; return TRUE; /* PS */ #endif /* COMPILE_PCRE8 */ default: return FALSE; } } /* End of pcre_newline.c */ pcre-8.31/pcre_valid_utf8.c0000644000222100022210000002362311676645217012552 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains an internal function for validating UTF-8 character strings. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Validate a UTF-8 string * *************************************************/ /* This function is called (optionally) at the start of compile or match, to check that a supposed UTF-8 string is actually valid. The early check means that subsequent code can assume it is dealing with a valid string. The check can be turned off for maximum performance, but the consequences of supplying an invalid string are then undefined. Originally, this function checked according to RFC 2279, allowing for values in the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in the canonical format. Once somebody had pointed out RFC 3629 to me (it obsoletes 2279), additional restrictions were applied. The values are now limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte characters is still checked. From release 8.13 more information about the details of the error are passed back in the returned value: PCRE_UTF8_ERR0 No error PCRE_UTF8_ERR1 Missing 1 byte at the end of the string PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80 PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80 PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80 PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80 PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80 PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629 PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629 PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted PCRE_UTF8_ERR15 Overlong 2-byte sequence PCRE_UTF8_ERR16 Overlong 3-byte sequence PCRE_UTF8_ERR17 Overlong 4-byte sequence PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur) PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur) PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character) PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff Arguments: string points to the string length length of string, or -1 if the string is zero-terminated errp pointer to an error position offset variable Returns: = 0 if the string is a valid UTF-8 string > 0 otherwise, setting the offset of the bad character */ int PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset) { #ifdef SUPPORT_UTF register PCRE_PUCHAR p; if (length < 0) { for (p = string; *p != 0; p++); length = (int)(p - string); } for (p = string; length-- > 0; p++) { register int ab, c, d; c = *p; if (c < 128) continue; /* ASCII character */ if (c < 0xc0) /* Isolated 10xx xxxx byte */ { *erroroffset = (int)(p - string); return PCRE_UTF8_ERR20; } if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */ { *erroroffset = (int)(p - string); return PCRE_UTF8_ERR21; } ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */ if (length < ab) { *erroroffset = (int)(p - string); /* Missing bytes */ return ab - length; /* Codes ERR1 to ERR5 */ } length -= ab; /* Length remaining */ /* Check top bits in the second byte */ if (((d = *(++p)) & 0xc0) != 0x80) { *erroroffset = (int)(p - string) - 1; return PCRE_UTF8_ERR6; } /* For each length, check that the remaining bytes start with the 0x80 bit set and not the 0x40 bit. Then check for an overlong sequence, and for the excluded range 0xd800 to 0xdfff. */ switch (ab) { /* 2-byte character. No further bytes to check for 0x80. Check first byte for for xx00 000x (overlong sequence). */ case 1: if ((c & 0x3e) == 0) { *erroroffset = (int)(p - string) - 1; return PCRE_UTF8_ERR15; } break; /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes for 1110 0000, xx0x xxxx (overlong sequence) or 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */ case 2: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR7; } if (c == 0xe0 && (d & 0x20) == 0) { *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR16; } if (c == 0xed && d >= 0xa0) { *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR14; } break; /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2 bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a character greater than 0x0010ffff (f4 8f bf bf) */ case 3: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { *erroroffset = (int)(p - string) - 3; return PCRE_UTF8_ERR8; } if (c == 0xf0 && (d & 0x30) == 0) { *erroroffset = (int)(p - string) - 3; return PCRE_UTF8_ERR17; } if (c > 0xf4 || (c == 0xf4 && d > 0x8f)) { *erroroffset = (int)(p - string) - 3; return PCRE_UTF8_ERR13; } break; /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be rejected by the length test below. However, we do the appropriate tests here so that overlong sequences get diagnosed, and also in case there is ever an option for handling these larger code points. */ /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for 1111 1000, xx00 0xxx */ case 4: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { *erroroffset = (int)(p - string) - 3; return PCRE_UTF8_ERR8; } if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ { *erroroffset = (int)(p - string) - 4; return PCRE_UTF8_ERR9; } if (c == 0xf8 && (d & 0x38) == 0) { *erroroffset = (int)(p - string) - 4; return PCRE_UTF8_ERR18; } break; /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for 1111 1100, xx00 00xx. */ case 5: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { *erroroffset = (int)(p - string) - 3; return PCRE_UTF8_ERR8; } if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ { *erroroffset = (int)(p - string) - 4; return PCRE_UTF8_ERR9; } if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */ { *erroroffset = (int)(p - string) - 5; return PCRE_UTF8_ERR10; } if (c == 0xfc && (d & 0x3c) == 0) { *erroroffset = (int)(p - string) - 5; return PCRE_UTF8_ERR19; } break; } /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are excluded by RFC 3629. The pointer p is currently at the last byte of the character. */ if (ab > 3) { *erroroffset = (int)(p - string) - ab; return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12; } } #else /* SUPPORT_UTF */ (void)(string); /* Keep picky compilers happy */ (void)(length); #endif return PCRE_UTF8_ERR0; /* This indicates success */ } /* End of pcre_valid_utf8.c */ pcre-8.31/configure.ac0000644000222100022210000010456511775524566011626 00000000000000dnl Process this file with autoconf to produce a configure script. dnl NOTE FOR MAINTAINERS: Do not use minor version numbers 08 or 09 because dnl the leading zeros may cause them to be treated as invalid octal constants dnl if a PCRE user writes code that uses PCRE_MINOR as a number. There is now dnl a check further down that throws an error if 08 or 09 are used. dnl The PCRE_PRERELEASE feature is for identifying release candidates. It might dnl be defined as -RC2, for example. For real releases, it should be empty. m4_define(pcre_major, [8]) m4_define(pcre_minor, [31]) m4_define(pcre_prerelease, []) m4_define(pcre_date, [2012-07-06]) # NOTE: The CMakeLists.txt file searches for the above variables in the first # 50 lines of this file. Please update that if the variables above are moved. # Libtool shared library interface versions (current:revision:age) m4_define(libpcre_version, [1:1:0]) m4_define(libpcre16_version, [0:1:0]) m4_define(libpcreposix_version, [0:1:0]) m4_define(libpcrecpp_version, [0:0:0]) AC_PREREQ(2.57) AC_INIT(PCRE, pcre_major.pcre_minor[]pcre_prerelease, , pcre) AC_CONFIG_SRCDIR([pcre.h.in]) AM_INIT_AUTOMAKE([dist-bzip2 dist-zip]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS(config.h) # This was added at the suggestion of libtoolize (03-Jan-10) AC_CONFIG_MACRO_DIR([m4]) # The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just # "-g" for any other compiler. There doesn't seem to be a standard way of # getting rid of the -g (which I don't think is needed for a production # library). This fudge seems to achieve the necessary. First, we remember the # externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and # AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not # set, they will be set to Autoconf's defaults. Afterwards, if the original # values were not set, remove the -g from the Autoconf defaults. # (PH 02-May-07) remember_set_CFLAGS="$CFLAGS" remember_set_CXXFLAGS="$CXXFLAGS" AC_PROG_CC AC_PROG_CXX if test "x$remember_set_CFLAGS" = "x" then if test "$CFLAGS" = "-g -O2" then CFLAGS="-O2" elif test "$CFLAGS" = "-g" then CFLAGS="" fi fi if test "x$remember_set_CXXFLAGS" = "x" then if test "$CXXFLAGS" = "-g -O2" then CXXFLAGS="-O2" elif test "$CXXFLAGS" = "-g" then CXXFLAGS="" fi fi # AC_PROG_CXX will return "g++" even if no c++ compiler is installed. # Check for that case, and just disable c++ code if g++ doesn't run. AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],, CXX=""; CXXCP=""; CXXFLAGS="") AC_LANG_POP # Check for a 64-bit integer type AC_TYPE_INT64_T AC_PROG_INSTALL AC_LIBTOOL_WIN32_DLL LT_INIT AC_PROG_LN_S PCRE_MAJOR="pcre_major" PCRE_MINOR="pcre_minor" PCRE_PRERELEASE="pcre_prerelease" PCRE_DATE="pcre_date" if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09" then echo "***" echo "*** Minor version number $PCRE_MINOR must not be used. ***" echo "*** Use only 01 to 07 or 10 onwards, to avoid octal issues. ***" echo "***" exit 1 fi AC_SUBST(PCRE_MAJOR) AC_SUBST(PCRE_MINOR) AC_SUBST(PCRE_PRERELEASE) AC_SUBST(PCRE_DATE) # Set a more sensible default value for $(htmldir). if test "x$htmldir" = 'x${docdir}' then htmldir='${docdir}/html' fi # Handle --disable-pcre8 (enabled by default) AC_ARG_ENABLE(pcre8, AS_HELP_STRING([--disable-pcre8], [disable 8 bit character support]), , enable_pcre8=unset) AC_SUBST(enable_pcre8) # Handle --enable-pcre16 (disabled by default) AC_ARG_ENABLE(pcre16, AS_HELP_STRING([--enable-pcre16], [enable 16 bit character support]), , enable_pcre16=unset) AC_SUBST(enable_pcre16) # Handle --disable-cpp. The substitution of enable_cpp is needed for use in # pcre-config. AC_ARG_ENABLE(cpp, AS_HELP_STRING([--disable-cpp], [disable C++ support]), , enable_cpp=unset) AC_SUBST(enable_cpp) # Handle --enable-jit (disabled by default) AC_ARG_ENABLE(jit, AS_HELP_STRING([--enable-jit], [enable Just-In-Time compiling support]), , enable_jit=no) # Handle --disable-pcregrep-jit (enabled by default) AC_ARG_ENABLE(pcregrep-jit, AS_HELP_STRING([--disable-pcregrep-jit], [disable JIT support in pcregrep]), , enable_pcregrep_jit=yes) # Handle --enable-rebuild-chartables AC_ARG_ENABLE(rebuild-chartables, AS_HELP_STRING([--enable-rebuild-chartables], [rebuild character tables in current locale]), , enable_rebuild_chartables=no) # Handle --enable-utf8 (disabled by default) AC_ARG_ENABLE(utf8, AS_HELP_STRING([--enable-utf8], [another name for --enable-utf. Kept only for compatibility reasons]), , enable_utf8=unset) # Handle --enable-utf (disabled by default) AC_ARG_ENABLE(utf, AS_HELP_STRING([--enable-utf], [enable UTF-8/16 support (incompatible with --enable-ebcdic)]), , enable_utf=unset) # Handle --enable-unicode-properties AC_ARG_ENABLE(unicode-properties, AS_HELP_STRING([--enable-unicode-properties], [enable Unicode properties support (implies --enable-utf)]), , enable_unicode_properties=no) # Handle --enable-newline=NL dnl AC_ARG_ENABLE(newline, dnl AS_HELP_STRING([--enable-newline=NL], dnl [use NL as newline (lf, cr, crlf, anycrlf, any; default=lf)]), dnl , enable_newline=lf) # Separate newline options ac_pcre_newline=lf AC_ARG_ENABLE(newline-is-cr, AS_HELP_STRING([--enable-newline-is-cr], [use CR as newline character]), ac_pcre_newline=cr) AC_ARG_ENABLE(newline-is-lf, AS_HELP_STRING([--enable-newline-is-lf], [use LF as newline character (default)]), ac_pcre_newline=lf) AC_ARG_ENABLE(newline-is-crlf, AS_HELP_STRING([--enable-newline-is-crlf], [use CRLF as newline sequence]), ac_pcre_newline=crlf) AC_ARG_ENABLE(newline-is-anycrlf, AS_HELP_STRING([--enable-newline-is-anycrlf], [use CR, LF, or CRLF as newline sequence]), ac_pcre_newline=anycrlf) AC_ARG_ENABLE(newline-is-any, AS_HELP_STRING([--enable-newline-is-any], [use any valid Unicode newline sequence]), ac_pcre_newline=any) enable_newline="$ac_pcre_newline" # Handle --enable-bsr-anycrlf AC_ARG_ENABLE(bsr-anycrlf, AS_HELP_STRING([--enable-bsr-anycrlf], [\R matches only CR, LF, CRLF by default]), , enable_bsr_anycrlf=no) # Handle --enable-ebcdic AC_ARG_ENABLE(ebcdic, AS_HELP_STRING([--enable-ebcdic], [assume EBCDIC coding rather than ASCII; incompatible with --enable-utf; use only in (uncommon) EBCDIC environments; it implies --enable-rebuild-chartables]), , enable_ebcdic=no) # Handle --disable-stack-for-recursion AC_ARG_ENABLE(stack-for-recursion, AS_HELP_STRING([--disable-stack-for-recursion], [don't use stack recursion when matching]), , enable_stack_for_recursion=yes) # Handle --enable-pcregrep-libz AC_ARG_ENABLE(pcregrep-libz, AS_HELP_STRING([--enable-pcregrep-libz], [link pcregrep with libz to handle .gz files]), , enable_pcregrep_libz=no) # Handle --enable-pcregrep-libbz2 AC_ARG_ENABLE(pcregrep-libbz2, AS_HELP_STRING([--enable-pcregrep-libbz2], [link pcregrep with libbz2 to handle .bz2 files]), , enable_pcregrep_libbz2=no) # Handle --with-pcregrep-bufsize=N AC_ARG_WITH(pcregrep-bufsize, AS_HELP_STRING([--with-pcregrep-bufsize=N], [pcregrep buffer size (default=20480)]), , with_pcregrep_bufsize=20480) # Handle --enable-pcretest-libedit AC_ARG_ENABLE(pcretest-libedit, AS_HELP_STRING([--enable-pcretest-libedit], [link pcretest with libedit]), , enable_pcretest_libedit=no) # Handle --enable-pcretest-libreadline AC_ARG_ENABLE(pcretest-libreadline, AS_HELP_STRING([--enable-pcretest-libreadline], [link pcretest with libreadline]), , enable_pcretest_libreadline=no) # Handle --with-posix-malloc-threshold=NBYTES AC_ARG_WITH(posix-malloc-threshold, AS_HELP_STRING([--with-posix-malloc-threshold=NBYTES], [threshold for POSIX malloc usage (default=10)]), , with_posix_malloc_threshold=10) # Handle --with-link-size=N AC_ARG_WITH(link-size, AS_HELP_STRING([--with-link-size=N], [internal link size (2, 3, or 4 allowed; default=2)]), , with_link_size=2) # Handle --with-match-limit=N AC_ARG_WITH(match-limit, AS_HELP_STRING([--with-match-limit=N], [default limit on internal looping (default=10000000)]), , with_match_limit=10000000) # Handle --with-match-limit_recursion=N # # Note: In config.h, the default is to define MATCH_LIMIT_RECURSION # symbolically as MATCH_LIMIT, which in turn is defined to be some numeric # value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some # different numeric value (or even the same numeric value as MATCH_LIMIT, # though no longer defined in terms of the latter). # AC_ARG_WITH(match-limit-recursion, AS_HELP_STRING([--with-match-limit-recursion=N], [default limit on internal recursion (default=MATCH_LIMIT)]), , with_match_limit_recursion=MATCH_LIMIT) # Copy enable_utf8 value to enable_utf for compatibility reasons if test "x$enable_utf8" != "xunset" then if test "x$enable_utf" != "xunset" then AC_MSG_ERROR([--enable/disable-utf8 is kept only for compatibility reasons and its value is copied to --enable/disable-utf. Newer code must use --enable/disable-utf alone.]) fi enable_utf=$enable_utf8 fi # Set the default value for pcre8 if test "x$enable_pcre8" = "xunset" then enable_pcre8=yes fi # Set the default value for pcre16 if test "x$enable_pcre16" = "xunset" then enable_pcre16=no fi # Make sure enable_pcre8 or enable_pcre16 was set if test "x$enable_pcre8$enable_pcre16" = "xnono" then AC_MSG_ERROR([Either 8 or 16 bit (or both) pcre library must be enabled]) fi # Make sure that if enable_unicode_properties was set, that UTF support is enabled. if test "x$enable_unicode_properties" = "xyes" then if test "x$enable_utf" = "xno" then AC_MSG_ERROR([support for Unicode properties requires UTF-8/16 support]) fi enable_utf=yes fi # enable_utf is disabled by default. if test "x$enable_utf" = "xunset" then enable_utf=no fi # enable_cpp copies the value of enable_pcre8 by default if test "x$enable_cpp" = "xunset" then enable_cpp=$enable_pcre8 fi # Make sure that if enable_cpp was set, that enable_pcre8 support is enabled if test "x$enable_cpp" = "xyes" then if test "x$enable_pcre8" = "xno" then AC_MSG_ERROR([C++ library requires pcre library with 8 bit characters]) fi fi # Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled. # Also check that UTF support is not requested, because PCRE cannot handle # EBCDIC and UTF in the same build. To do so it would need to use different # character constants depending on the mode. # if test "x$enable_ebcdic" = "xyes" then enable_rebuild_chartables=yes if test "x$enable_utf" = "xyes" then AC_MSG_ERROR([support for EBCDIC and UTF-8/16 cannot be enabled at the same time]) fi fi # Convert the newline identifier into the appropriate integer value. case "$enable_newline" in lf) ac_pcre_newline_value=10 ;; cr) ac_pcre_newline_value=13 ;; crlf) ac_pcre_newline_value=3338 ;; anycrlf) ac_pcre_newline_value=-2 ;; any) ac_pcre_newline_value=-1 ;; *) AC_MSG_ERROR([invalid argument \"$enable_newline\" to --enable-newline option]) ;; esac # Check argument to --with-link-size case "$with_link_size" in 2|3|4) ;; *) AC_MSG_ERROR([invalid argument \"$with_link_size\" to --with-link-size option]) ;; esac AH_TOP([ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, so that config.h is included at the start of every source. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */]) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h windows.h) # The files below are C++ header files. pcre_have_type_traits="0" pcre_have_bits_type_traits="0" if test "x$enable_cpp" = "xyes" -a -n "$CXX" then AC_LANG_PUSH(C++) # Older versions of pcre defined pcrecpp::no_arg, but in new versions # it's called pcrecpp::RE::no_arg. For backwards ABI compatibility, # we want to make one an alias for the other. Different systems do # this in different ways. Some systems, for instance, can do it via # a linker flag: -alias (for os x 10.5) or -i (for os x <=10.4). OLD_LDFLAGS="$LDFLAGS" for flag in "-alias,__ZN7pcrecpp2RE6no_argE,__ZN7pcrecpp6no_argE" \ "-i__ZN7pcrecpp6no_argE:__ZN7pcrecpp2RE6no_argE"; do AC_MSG_CHECKING([for alias support in the linker]) LDFLAGS="$OLD_LDFLAGS -Wl,$flag" # We try to run the linker with this new ld flag. If the link fails, # we give up and remove the new flag from LDFLAGS. AC_LINK_IFELSE([AC_LANG_PROGRAM([namespace pcrecpp { class RE { static int no_arg; }; int RE::no_arg; }], [])], [AC_MSG_RESULT([yes]); EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS -Wl,$flag"; break;], AC_MSG_RESULT([no])) done LDFLAGS="$OLD_LDFLAGS" # We could be more clever here, given we're doing AC_SUBST with this # (eg set a var to be the name of the include file we want). But we're not # so it's easy to change back to 'regular' autoconf vars if we needed to. AC_CHECK_HEADERS(string, [pcre_have_cpp_headers="1"], [pcre_have_cpp_headers="0"]) AC_CHECK_HEADERS(bits/type_traits.h, [pcre_have_bits_type_traits="1"], [pcre_have_bits_type_traits="0"]) AC_CHECK_HEADERS(type_traits.h, [pcre_have_type_traits="1"], [pcre_have_type_traits="0"]) # (This isn't c++-specific, but is only used in pcrecpp.cc, so try this # in a c++ context. This matters becuase strtoimax is C99 and may not # be supported by the C++ compiler.) # Figure out how to create a longlong from a string: strtoll and # equiv. It's not enough to call AC_CHECK_FUNCS: hpux has a # strtoll, for instance, but it only takes 2 args instead of 3! # We have to call AH_TEMPLATE since AC_DEFINE_UNQUOTED below is complex. AH_TEMPLATE(HAVE_STRTOQ, [Define to 1 if you have `strtoq'.]) AH_TEMPLATE(HAVE_STRTOLL, [Define to 1 if you have `strtoll'.]) AH_TEMPLATE(HAVE__STRTOI64, [Define to 1 if you have `_strtoi64'.]) AH_TEMPLATE(HAVE_STRTOIMAX, [Define to 1 if you have `strtoimax'.]) have_strto_fn=0 for fn in strtoq strtoll _strtoi64 strtoimax; do AC_MSG_CHECKING([for $fn]) if test "$fn" = strtoimax; then include=stdint.h else include=stdlib.h fi AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <$include>], [char* e; return $fn("100", &e, 10)])], [AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED(HAVE_`echo $fn | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`, 1, [Define to 1 if you have `$fn'.]) have_strto_fn=1 break], [AC_MSG_RESULT(no)]) done if test "$have_strto_fn" = 1; then AC_CHECK_TYPES([long long], [pcre_have_long_long="1"], [pcre_have_long_long="0"]) AC_CHECK_TYPES([unsigned long long], [pcre_have_ulong_long="1"], [pcre_have_ulong_long="0"]) else pcre_have_long_long="0" pcre_have_ulong_long="0" fi AC_SUBST(pcre_have_long_long) AC_SUBST(pcre_have_ulong_long) AC_LANG_POP fi # Using AC_SUBST eliminates the need to include config.h in a public .h file AC_SUBST(pcre_have_type_traits) AC_SUBST(pcre_have_bits_type_traits) # Conditional compilation AM_CONDITIONAL(WITH_PCRE8, test "x$enable_pcre8" = "xyes") AM_CONDITIONAL(WITH_PCRE16, test "x$enable_pcre16" = "xyes") AM_CONDITIONAL(WITH_PCRE_CPP, test "x$enable_cpp" = "xyes") AM_CONDITIONAL(WITH_REBUILD_CHARTABLES, test "x$enable_rebuild_chartables" = "xyes") AM_CONDITIONAL(WITH_JIT, test "x$enable_jit" = "xyes") AM_CONDITIONAL(WITH_UTF, test "x$enable_utf" = "xyes") # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T # Checks for library functions. AC_CHECK_FUNCS(bcopy memmove strerror) # Check for the availability of libz (aka zlib) AC_CHECK_HEADERS([zlib.h], [HAVE_ZLIB_H=1]) AC_CHECK_LIB([z], [gzopen], [HAVE_LIBZ=1]) # Check for the availability of libbz2. Originally we just used AC_CHECK_LIB, # as for libz. However, this had the following problem, diagnosed and fixed by # a user: # # - libbz2 uses the Pascal calling convention (WINAPI) for the functions # under Win32. # - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", # therefore missing the function definition. # - The compiler thus generates a "C" signature for the test function. # - The linker fails to find the "C" function. # - PCRE fails to configure if asked to do so against libbz2. # # Solution: # # - Replace the AC_CHECK_LIB test with a custom test. AC_CHECK_HEADERS([bzlib.h], [HAVE_BZLIB_H=1]) # Original test # AC_CHECK_LIB([bz2], [BZ2_bzopen], [HAVE_LIBBZ2=1]) # # Custom test follows AC_MSG_CHECKING([for libbz2]) OLD_LIBS="$LIBS" LIBS="$LIBS -lbz2" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #ifdef HAVE_BZLIB_H #include #endif]], [[return (int)BZ2_bzopen("conftest", "rb");]])], [AC_MSG_RESULT([yes]);HAVE_LIBBZ2=1; break;], AC_MSG_RESULT([no])) LIBS="$OLD_LIBS" # Check for the availabiity of libreadline if test "$enable_pcretest_libreadline" = "yes"; then AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_H=1]) AC_CHECK_HEADERS([readline/history.h], [HAVE_HISTORY_H=1]) AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lreadline"], [unset ac_cv_lib_readline_readline; AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltinfo"], [unset ac_cv_lib_readline_readline; AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lcurses"], [unset ac_cv_lib_readline_readline; AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncurses"], [unset ac_cv_lib_readline_readline; AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncursesw"], [unset ac_cv_lib_readline_readline; AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltermcap"], [LIBREADLINE=""], [-ltermcap])], [-lncursesw])], [-lncurses])], [-lcurses])], [-ltinfo])]) AC_SUBST(LIBREADLINE) if test -n "$LIBREADLINE"; then if test "$LIBREADLINE" != "-lreadline"; then echo "-lreadline needs $LIBREADLINE" LIBREADLINE="-lreadline $LIBREADLINE" fi fi fi # Check for the availability of libedit. Different distributions put its # headers in different places. Try to cover the most common ones. if test "$enable_pcretest_libedit" = "yes"; then AC_CHECK_HEADERS([editline/readline.h], [HAVE_EDITLINE_READLINE_H=1], [AC_CHECK_HEADERS([edit/readline/readline.h], [HAVE_READLINE_READLINE_H=1], [AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_READLINE_H=1])])]) AC_CHECK_LIB([edit], [readline], [LIBEDIT="-ledit"]) fi # This facilitates -ansi builds under Linux dnl AC_DEFINE([_GNU_SOURCE], [], [Enable GNU extensions in glibc]) PCRE_STATIC_CFLAG="" if test "x$enable_shared" = "xno" ; then AC_DEFINE([PCRE_STATIC], [1], [ Define if linking statically (TODO: make nice with Libtool)]) PCRE_STATIC_CFLAG="-DPCRE_STATIC" fi AC_SUBST(PCRE_STATIC_CFLAG) # Here is where pcre specific defines are handled if test "$enable_pcre8" = "yes"; then AC_DEFINE([SUPPORT_PCRE8], [], [ Define to enable the 8 bit PCRE library.]) fi if test "$enable_pcre16" = "yes"; then AC_DEFINE([SUPPORT_PCRE16], [], [ Define to enable the 16 bit PCRE library.]) fi if test "$enable_jit" = "yes"; then AC_DEFINE([SUPPORT_JIT], [], [ Define to enable support for Just-In-Time compiling.]) else enable_pcregrep_jit="no" fi if test "$enable_pcregrep_jit" = "yes"; then AC_DEFINE([SUPPORT_PCREGREP_JIT], [], [ Define to enable JIT support in pcregrep.]) fi if test "$enable_utf" = "yes"; then AC_DEFINE([SUPPORT_UTF], [], [ Define to enable support for the UTF-8/16 Unicode encoding. This will work even in an EBCDIC environment, but it is incompatible with the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8/16, but not both at once.]) fi if test "$enable_unicode_properties" = "yes"; then AC_DEFINE([SUPPORT_UCP], [], [ Define to enable support for Unicode properties.]) fi if test "$enable_stack_for_recursion" = "no"; then AC_DEFINE([NO_RECURSE], [], [ PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion).]) fi if test "$enable_pcregrep_libz" = "yes"; then AC_DEFINE([SUPPORT_LIBZ], [], [ Define to allow pcregrep to be linked with libz, so that it is able to handle .gz files.]) fi if test "$enable_pcregrep_libbz2" = "yes"; then AC_DEFINE([SUPPORT_LIBBZ2], [], [ Define to allow pcregrep to be linked with libbz2, so that it is able to handle .bz2 files.]) fi if test $with_pcregrep_bufsize -lt 8192 ; then with_pcregrep_bufsize="8192" fi AC_DEFINE_UNQUOTED([PCREGREP_BUFSIZE], [$with_pcregrep_bufsize], [ The value of PCREGREP_BUFSIZE determines the size of buffer used by pcregrep to hold parts of the file it is searching. On systems that support it, "configure" can be used to override the default, which is 8192. This is also the minimum value. The actual amount of memory used by pcregrep is three times this number, because it allows for the buffering of "before" and "after" lines.]) if test "$enable_pcretest_libedit" = "yes"; then AC_DEFINE([SUPPORT_LIBEDIT], [], [ Define to allow pcretest to be linked with libedit.]) LIBREADLINE="$LIBEDIT" elif test "$enable_pcretest_libreadline" = "yes"; then AC_DEFINE([SUPPORT_LIBREADLINE], [], [ Define to allow pcretest to be linked with libreadline.]) fi AC_DEFINE_UNQUOTED([NEWLINE], [$ac_pcre_newline_value], [ The value of NEWLINE determines the newline character sequence. On systems that support it, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF).]) if test "$enable_bsr_anycrlf" = "yes"; then AC_DEFINE([BSR_ANYCRLF], [], [ By default, the \R escape sequence matches any Unicode line ending character or sequence of characters. If BSR_ANYCRLF is defined, this is changed so that backslash-R matches only CR, LF, or CRLF. The build- time default can be overridden by the user of PCRE at runtime. On systems that support it, "configure" can be used to override the default.]) fi AC_DEFINE_UNQUOTED([LINK_SIZE], [$with_link_size], [ The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default.]) AC_DEFINE_UNQUOTED([POSIX_MALLOC_THRESHOLD], [$with_posix_malloc_threshold], [ When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default.]) AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [ The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default.]) AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [ The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default.]) AC_DEFINE([MAX_NAME_SIZE], [32], [ This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns.]) AC_DEFINE([MAX_NAME_COUNT], [10000], [ This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns.]) AH_VERBATIM([PCRE_EXP_DEFN], [ /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ #undef PCRE_EXP_DEFN]) if test "$enable_ebcdic" = "yes"; then AC_DEFINE_UNQUOTED([EBCDIC], [], [ If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. PCRE will then assume that all input strings are in EBCDIC. If you do not define this macro, PCRE will assume input strings are ASCII or UTF-8/16 Unicode. It is not possible to build a version of PCRE that supports both EBCDIC and UTF-8/16.]) fi # Platform specific issues NO_UNDEFINED= EXPORT_ALL_SYMBOLS= case $host_os in cygwin* | mingw* ) if test X"$enable_shared" = Xyes; then NO_UNDEFINED="-no-undefined" EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" fi ;; esac # The extra LDFLAGS for each particular library # (Note: The libpcre*_version bits are m4 variables, assigned above) EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ $NO_UNDEFINED -version-info libpcre_version" EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ $NO_UNDEFINED -version-info libpcre16_version" EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ $NO_UNDEFINED -version-info libpcreposix_version" EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ $NO_UNDEFINED -version-info libpcrecpp_version \ $EXPORT_ALL_SYMBOLS" AC_SUBST(EXTRA_LIBPCRE_LDFLAGS) AC_SUBST(EXTRA_LIBPCRE16_LDFLAGS) AC_SUBST(EXTRA_LIBPCREPOSIX_LDFLAGS) AC_SUBST(EXTRA_LIBPCRECPP_LDFLAGS) # When we run 'make distcheck', use these arguments. Turning off compiler # optimization makes it run faster. DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre16 --enable-jit --enable-cpp --enable-unicode-properties" AC_SUBST(DISTCHECK_CONFIGURE_FLAGS) # Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is # specified, the relevant library is available. if test "$enable_pcregrep_libz" = "yes"; then if test "$HAVE_ZLIB_H" != "1"; then echo "** Cannot --enable-pcregrep-libz because zlib.h was not found" exit 1 fi if test "$HAVE_LIBZ" != "1"; then echo "** Cannot --enable-pcregrep-libz because libz was not found" exit 1 fi LIBZ="-lz" fi AC_SUBST(LIBZ) if test "$enable_pcregrep_libbz2" = "yes"; then if test "$HAVE_BZLIB_H" != "1"; then echo "** Cannot --enable-pcregrep-libbz2 because bzlib.h was not found" exit 1 fi if test "$HAVE_LIBBZ2" != "1"; then echo "** Cannot --enable-pcregrep-libbz2 because libbz2 was not found" exit 1 fi LIBBZ2="-lbz2" fi AC_SUBST(LIBBZ2) # Similarly for --enable-pcretest-readline if test "$enable_pcretest_libedit" = "yes"; then if test "$enable_pcretest_libreadline" = "yes"; then echo "** Cannot use both --enable-pcretest-libedit and --enable-pcretest-readline" exit 1 fi if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ "$HAVE_READLINE_READLINE_H" != "1"; then echo "** Cannot --enable-pcretest-libedit because neither editline/readline.h" echo "** nor readline/readline.h was found." exit 1 fi if test -z "$LIBEDIT"; then echo "** Cannot --enable-pcretest-libedit because libedit library was not found." exit 1 fi fi if test "$enable_pcretest_libreadline" = "yes"; then if test "$HAVE_READLINE_H" != "1"; then echo "** Cannot --enable-pcretest-readline because readline/readline.h was not found." exit 1 fi if test "$HAVE_HISTORY_H" != "1"; then echo "** Cannot --enable-pcretest-readline because readline/history.h was not found." exit 1 fi if test -z "$LIBREADLINE"; then echo "** Cannot --enable-pcretest-readline because readline library was not found." exit 1 fi fi # Produce these files, in addition to config.h. AC_CONFIG_FILES( Makefile libpcre.pc libpcre16.pc libpcreposix.pc libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h ) # Make the generated script files executable. AC_CONFIG_COMMANDS([script-chmod], [chmod a+x pcre-config]) # Make sure that pcre_chartables.c is removed in case the method for # creating it was changed by reconfiguration. AC_CONFIG_COMMANDS([delete-old-chartables], [rm -f pcre_chartables.c]) AC_OUTPUT # Print out a nice little message after configure is run displaying your # chosen options. cat <= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and 16-bit PCRE libraries. --/ /the quick brown fox/ the quick brown fox 0: the quick brown fox The quick brown FOX No match What do you know about the quick brown fox? 0: the quick brown fox What do you know about THE QUICK BROWN FOX? No match /The quick brown fox/i the quick brown fox 0: the quick brown fox The quick brown FOX 0: The quick brown FOX What do you know about the quick brown fox? 0: the quick brown fox What do you know about THE QUICK BROWN FOX? 0: THE QUICK BROWN FOX /abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ abcd\t\n\r\f\a\e9;\$\\?caxyz 0: abcd\x09\x0a\x0d\x0c\x07\x1b9;$\?caxyz /a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ abxyzpqrrrabbxyyyypqAzz 0: abxyzpqrrrabbxyyyypqAzz abxyzpqrrrabbxyyyypqAzz 0: abxyzpqrrrabbxyyyypqAzz aabxyzpqrrrabbxyyyypqAzz 0: aabxyzpqrrrabbxyyyypqAzz aaabxyzpqrrrabbxyyyypqAzz 0: aaabxyzpqrrrabbxyyyypqAzz aaaabxyzpqrrrabbxyyyypqAzz 0: aaaabxyzpqrrrabbxyyyypqAzz abcxyzpqrrrabbxyyyypqAzz 0: abcxyzpqrrrabbxyyyypqAzz aabcxyzpqrrrabbxyyyypqAzz 0: aabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypAzz 0: aaabcxyzpqrrrabbxyyyypAzz aaabcxyzpqrrrabbxyyyypqAzz 0: aaabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypqqAzz 0: aaabcxyzpqrrrabbxyyyypqqAzz aaabcxyzpqrrrabbxyyyypqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqAzz aaabcxyzpqrrrabbxyyyypqqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz aaaabcxyzpqrrrabbxyyyypqAzz 0: aaaabcxyzpqrrrabbxyyyypqAzz abxyzzpqrrrabbxyyyypqAzz 0: abxyzzpqrrrabbxyyyypqAzz aabxyzzzpqrrrabbxyyyypqAzz 0: aabxyzzzpqrrrabbxyyyypqAzz aaabxyzzzzpqrrrabbxyyyypqAzz 0: aaabxyzzzzpqrrrabbxyyyypqAzz aaaabxyzzzzpqrrrabbxyyyypqAzz 0: aaaabxyzzzzpqrrrabbxyyyypqAzz abcxyzzpqrrrabbxyyyypqAzz 0: abcxyzzpqrrrabbxyyyypqAzz aabcxyzzzpqrrrabbxyyyypqAzz 0: aabcxyzzzpqrrrabbxyyyypqAzz aaabcxyzzzzpqrrrabbxyyyypqAzz 0: aaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbxyyyypqAzz 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyypqAzz 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyyypqAzz 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz aaabcxyzpqrrrabbxyyyypABzz 0: aaabcxyzpqrrrabbxyyyypABzz aaabcxyzpqrrrabbxyyyypABBzz 0: aaabcxyzpqrrrabbxyyyypABBzz >>>aaabxyzpqrrrabbxyyyypqAzz 0: aaabxyzpqrrrabbxyyyypqAzz >aaaabxyzpqrrrabbxyyyypqAzz 0: aaaabxyzpqrrrabbxyyyypqAzz >>>>abcxyzpqrrrabbxyyyypqAzz 0: abcxyzpqrrrabbxyyyypqAzz *** Failers No match abxyzpqrrabbxyyyypqAzz No match abxyzpqrrrrabbxyyyypqAzz No match abxyzpqrrrabxyyyypqAzz No match aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz No match aaaabcxyzzzzpqrrrabbbxyyypqAzz No match aaabcxyzpqrrrabbxyyyypqqqqqqqAzz No match /^(abc){1,2}zz/ abczz 0: abczz 1: abc abcabczz 0: abcabczz 1: abc *** Failers No match zz No match abcabcabczz No match >>abczz No match /^(b+?|a){1,2}?c/ bc 0: bc 1: b bbc 0: bbc 1: b bbbc 0: bbbc 1: bb bac 0: bac 1: a bbac 0: bbac 1: a aac 0: aac 1: a abbbbbbbbbbbc 0: abbbbbbbbbbbc 1: bbbbbbbbbbb bbbbbbbbbbbac 0: bbbbbbbbbbbac 1: a *** Failers No match aaac No match abbbbbbbbbbbac No match /^(b+|a){1,2}c/ bc 0: bc 1: b bbc 0: bbc 1: bb bbbc 0: bbbc 1: bbb bac 0: bac 1: a bbac 0: bbac 1: a aac 0: aac 1: a abbbbbbbbbbbc 0: abbbbbbbbbbbc 1: bbbbbbbbbbb bbbbbbbbbbbac 0: bbbbbbbbbbbac 1: a *** Failers No match aaac No match abbbbbbbbbbbac No match /^(b+|a){1,2}?bc/ bbc 0: bbc 1: b /^(b*|ba){1,2}?bc/ babc 0: babc 1: ba bbabc 0: bbabc 1: ba bababc 0: bababc 1: ba *** Failers No match bababbc No match babababc No match /^(ba|b*){1,2}?bc/ babc 0: babc 1: ba bbabc 0: bbabc 1: ba bababc 0: bababc 1: ba *** Failers No match bababbc No match babababc No match /^\ca\cA\c[\c{\c:/ \x01\x01\e;z 0: \x01\x01\x1b;z /^[ab\]cde]/ athing 0: a bthing 0: b ]thing 0: ] cthing 0: c dthing 0: d ething 0: e *** Failers No match fthing No match [thing No match \\thing No match /^[]cde]/ ]thing 0: ] cthing 0: c dthing 0: d ething 0: e *** Failers No match athing No match fthing No match /^[^ab\]cde]/ fthing 0: f [thing 0: [ \\thing 0: \ *** Failers 0: * athing No match bthing No match ]thing No match cthing No match dthing No match ething No match /^[^]cde]/ athing 0: a fthing 0: f *** Failers 0: * ]thing No match cthing No match dthing No match ething No match /^\/ 0: \x81 /^ÿ/ ÿ 0: \xff /^[0-9]+$/ 0 0: 0 1 0: 1 2 0: 2 3 0: 3 4 0: 4 5 0: 5 6 0: 6 7 0: 7 8 0: 8 9 0: 9 10 0: 10 100 0: 100 *** Failers No match abc No match /^.*nter/ enter 0: enter inter 0: inter uponter 0: uponter /^xxx[0-9]+$/ xxx0 0: xxx0 xxx1234 0: xxx1234 *** Failers No match xxx No match /^.+[0-9][0-9][0-9]$/ x123 0: x123 xx123 0: xx123 123456 0: 123456 *** Failers No match 123 No match x1234 0: x1234 /^.+?[0-9][0-9][0-9]$/ x123 0: x123 xx123 0: xx123 123456 0: 123456 *** Failers No match 123 No match x1234 0: x1234 /^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ abc!pqr=apquxz.ixr.zzz.ac.uk 0: abc!pqr=apquxz.ixr.zzz.ac.uk 1: abc 2: pqr *** Failers No match !pqr=apquxz.ixr.zzz.ac.uk No match abc!=apquxz.ixr.zzz.ac.uk No match abc!pqr=apquxz:ixr.zzz.ac.uk No match abc!pqr=apquxz.ixr.zzz.ac.ukk No match /:/ Well, we need a colon: somewhere 0: : *** Fail if we don't No match /([\da-f:]+)$/i 0abc 0: 0abc 1: 0abc abc 0: abc 1: abc fed 0: fed 1: fed E 0: E 1: E :: 0: :: 1: :: 5f03:12C0::932e 0: 5f03:12C0::932e 1: 5f03:12C0::932e fed def 0: def 1: def Any old stuff 0: ff 1: ff *** Failers No match 0zzz No match gzzz No match fed\x20 No match Any old rubbish No match /^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ .1.2.3 0: .1.2.3 1: 1 2: 2 3: 3 A.12.123.0 0: A.12.123.0 1: 12 2: 123 3: 0 *** Failers No match .1.2.3333 No match 1.2.3 No match 1234.2.3 No match /^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ 1 IN SOA non-sp1 non-sp2( 0: 1 IN SOA non-sp1 non-sp2( 1: 1 2: non-sp1 3: non-sp2 1 IN SOA non-sp1 non-sp2 ( 0: 1 IN SOA non-sp1 non-sp2 ( 1: 1 2: non-sp1 3: non-sp2 *** Failers No match 1IN SOA non-sp1 non-sp2( No match /^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ a. 0: a. Z. 0: Z. 2. 0: 2. ab-c.pq-r. 0: ab-c.pq-r. 1: .pq-r sxk.zzz.ac.uk. 0: sxk.zzz.ac.uk. 1: .uk x-.y-. 0: x-.y-. 1: .y- *** Failers No match -abc.peq. No match /^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ *.a 0: *.a *.b0-a 0: *.b0-a 1: 0-a *.c3-b.c 0: *.c3-b.c 1: 3-b 2: .c *.c-a.b-c 0: *.c-a.b-c 1: -a 2: .b-c 3: -c *** Failers No match *.0 No match *.a- No match *.a-b.c- No match *.c-a.0-c No match /^(?=ab(de))(abd)(e)/ abde 0: abde 1: de 2: abd 3: e /^(?!(ab)de|x)(abd)(f)/ abdf 0: abdf 1: 2: abd 3: f /^(?=(ab(cd)))(ab)/ abcd 0: ab 1: abcd 2: cd 3: ab /^[\da-f](\.[\da-f])*$/i a.b.c.d 0: a.b.c.d 1: .d A.B.C.D 0: A.B.C.D 1: .D a.b.c.1.2.3.C 0: a.b.c.1.2.3.C 1: .C /^\".*\"\s*(;.*)?$/ \"1234\" 0: "1234" \"abcd\" ; 0: "abcd" ; 1: ; \"\" ; rhubarb 0: "" ; rhubarb 1: ; rhubarb *** Failers No match \"1234\" : things No match /^$/ \ 0: *** Failers No match / ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x ab c 0: ab c *** Failers No match abc No match ab cde No match /(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ ab c 0: ab c *** Failers No match abc No match ab cde No match /^ a\ b[c ]d $/x a bcd 0: a bcd a b d 0: a b d *** Failers No match abcd No match ab d No match /^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ abcdefhijklm 0: abcdefhijklm 1: abc 2: bc 3: c 4: def 5: ef 6: f 7: hij 8: ij 9: j 10: klm 11: lm 12: m /^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ abcdefhijklm 0: abcdefhijklm 1: bc 2: c 3: ef 4: f 5: ij 6: j 7: lm 8: m /^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ a+ Z0+\x08\n\x1d\x12 0: a+ Z0+\x08\x0a\x1d\x12 /^[.^$|()*+?{,}]+/ .^\$(*+)|{?,?} 0: .^$(*+)|{?,?} /^a*\w/ z 0: z az 0: az aaaz 0: aaaz a 0: a aa 0: aa aaaa 0: aaaa a+ 0: a aa+ 0: aa /^a*?\w/ z 0: z az 0: a aaaz 0: a a 0: a aa 0: a aaaa 0: a a+ 0: a aa+ 0: a /^a+\w/ az 0: az aaaz 0: aaaz aa 0: aa aaaa 0: aaaa aa+ 0: aa /^a+?\w/ az 0: az aaaz 0: aa aa 0: aa aaaa 0: aa aa+ 0: aa /^\d{8}\w{2,}/ 1234567890 0: 1234567890 12345678ab 0: 12345678ab 12345678__ 0: 12345678__ *** Failers No match 1234567 No match /^[aeiou\d]{4,5}$/ uoie 0: uoie 1234 0: 1234 12345 0: 12345 aaaaa 0: aaaaa *** Failers No match 123456 No match /^[aeiou\d]{4,5}?/ uoie 0: uoie 1234 0: 1234 12345 0: 1234 aaaaa 0: aaaa 123456 0: 1234 /\A(abc|def)=(\1){2,3}\Z/ abc=abcabc 0: abc=abcabc 1: abc 2: abc def=defdefdef 0: def=defdefdef 1: def 2: def *** Failers No match abc=defdef No match /^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ abcdefghijkcda2 0: abcdefghijkcda2 1: a 2: b 3: c 4: d 5: e 6: f 7: g 8: h 9: i 10: j 11: k 12: cd abcdefghijkkkkcda2 0: abcdefghijkkkkcda2 1: a 2: b 3: c 4: d 5: e 6: f 7: g 8: h 9: i 10: j 11: k 12: cd /(cat(a(ract|tonic)|erpillar)) \1()2(3)/ cataract cataract23 0: cataract cataract23 1: cataract 2: aract 3: ract 4: 5: 3 catatonic catatonic23 0: catatonic catatonic23 1: catatonic 2: atonic 3: tonic 4: 5: 3 caterpillar caterpillar23 0: caterpillar caterpillar23 1: caterpillar 2: erpillar 3: 4: 5: 3 /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ From abcd Mon Sep 01 12:33:02 1997 0: From abcd Mon Sep 01 12:33 1: abcd /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ From abcd Mon Sep 01 12:33:02 1997 0: From abcd Mon Sep 01 12:33 1: Sep From abcd Mon Sep 1 12:33:02 1997 0: From abcd Mon Sep 1 12:33 1: Sep *** Failers No match From abcd Sep 01 12:33:02 1997 No match /^12.34/s 12\n34 0: 12\x0a34 12\r34 0: 12\x0d34 /\w+(?=\t)/ the quick brown\t fox 0: brown /foo(?!bar)(.*)/ foobar is foolish see? 0: foolish see? 1: lish see? /(?:(?!foo)...|^.{0,2})bar(.*)/ foobar crowbar etc 0: rowbar etc 1: etc barrel 0: barrel 1: rel 2barrel 0: 2barrel 1: rel A barrel 0: A barrel 1: rel /^(\D*)(?=\d)(?!123)/ abc456 0: abc 1: abc *** Failers No match abc123 No match /^1234(?# test newlines inside)/ 1234 0: 1234 /^1234 #comment in extended re /x 1234 0: 1234 /#rhubarb abcd/x abcd 0: abcd /^abcd#rhubarb/x abcd 0: abcd /^(a)\1{2,3}(.)/ aaab 0: aaab 1: a 2: b aaaab 0: aaaab 1: a 2: b aaaaab 0: aaaaa 1: a 2: a aaaaaab 0: aaaaa 1: a 2: a /(?!^)abc/ the abc 0: abc *** Failers No match abc No match /(?=^)abc/ abc 0: abc *** Failers No match the abc No match /^[ab]{1,3}(ab*|b)/ aabbbbb 0: aabb 1: b /^[ab]{1,3}?(ab*|b)/ aabbbbb 0: aabbbbb 1: abbbbb /^[ab]{1,3}?(ab*?|b)/ aabbbbb 0: aa 1: a /^[ab]{1,3}(ab*?|b)/ aabbbbb 0: aabb 1: b / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /x Alan Other 0: Alan Other 0: user@dom.ain user\@dom.ain 0: user@dom.ain \"A. Other\" (a comment) 0: "A. Other" (a comment) A. Other (a comment) 0: Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) # leading word [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces (?: (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) | " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " ) # "special" comment or quoted string [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" )* < [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # < (?: @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* (?: , [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* )* # additional domains : [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address spec > # > # name and address ) /x Alan Other 0: Alan Other 0: user@dom.ain user\@dom.ain 0: user@dom.ain \"A. Other\" (a comment) 0: "A. Other" A. Other (a comment) 0: Other \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay A missing angle ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff /P[^*]TAIRE[^*]{1,6}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx 0: PSTAIREISLL /P[^*]TAIRE[^*]{1,}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx 0: PSTAIREISLL /(\.\d\d[1-9]?)\d+/ 1.230003938 0: .230003938 1: .23 1.875000282 0: .875000282 1: .875 1.235 0: .235 1: .23 /(\.\d\d((?=0)|\d(?=\d)))/ 1.230003938 0: .23 1: .23 2: 1.875000282 0: .875 1: .875 2: 5 *** Failers No match 1.235 No match /a(?)b/ ab 0: ab /\b(foo)\s+(\w+)/i Food is on the foo table 0: foo table 1: foo 2: table /foo(.*)bar/ The food is under the bar in the barn. 0: food is under the bar in the bar 1: d is under the bar in the /foo(.*?)bar/ The food is under the bar in the barn. 0: food is under the bar 1: d is under the /(.*)(\d*)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 53147 2: /(.*)(\d+)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: 7 /(.*?)(\d*)/ I have 2 numbers: 53147 0: 1: 2: /(.*?)(\d+)/ I have 2 numbers: 53147 0: I have 2 1: I have 2: 2 /(.*)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: 7 /(.*?)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 2: 53147 /(.*)\b(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 2: 53147 /(.*\D)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 2: 53147 /^\D*(?!123)/ ABC123 0: AB /^(\D*)(?=\d)(?!123)/ ABC445 0: ABC 1: ABC *** Failers No match ABC123 No match /^[W-]46]/ W46]789 0: W46] -46]789 0: -46] *** Failers No match Wall No match Zebra No match 42 No match [abcd] No match ]abcd[ No match /^[W-\]46]/ W46]789 0: W Wall 0: W Zebra 0: Z Xylophone 0: X 42 0: 4 [abcd] 0: [ ]abcd[ 0: ] \\backslash 0: \ *** Failers No match -46]789 No match well No match /\d\d\/\d\d\/\d\d\d\d/ 01/01/2000 0: 01/01/2000 /word (?:[a-zA-Z0-9]+ ){0,10}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark No match /word (?:[a-zA-Z0-9]+ ){0,300}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match /^(a){0,0}/ bcd 0: abc 0: aab 0: /^(a){0,1}/ bcd 0: abc 0: a 1: a aab 0: a 1: a /^(a){0,2}/ bcd 0: abc 0: a 1: a aab 0: aa 1: a /^(a){0,3}/ bcd 0: abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a /^(a){0,}/ bcd 0: abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a aaaaaaaa 0: aaaaaaaa 1: a /^(a){1,1}/ bcd No match abc 0: a 1: a aab 0: a 1: a /^(a){1,2}/ bcd No match abc 0: a 1: a aab 0: aa 1: a /^(a){1,3}/ bcd No match abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a /^(a){1,}/ bcd No match abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a aaaaaaaa 0: aaaaaaaa 1: a /.*\.gif/ borfle\nbib.gif\nno 0: bib.gif /.{0,}\.gif/ borfle\nbib.gif\nno 0: bib.gif /.*\.gif/m borfle\nbib.gif\nno 0: bib.gif /.*\.gif/s borfle\nbib.gif\nno 0: borfle\x0abib.gif /.*\.gif/ms borfle\nbib.gif\nno 0: borfle\x0abib.gif /.*$/ borfle\nbib.gif\nno 0: no /.*$/m borfle\nbib.gif\nno 0: borfle /.*$/s borfle\nbib.gif\nno 0: borfle\x0abib.gif\x0ano /.*$/ms borfle\nbib.gif\nno 0: borfle\x0abib.gif\x0ano /.*$/ borfle\nbib.gif\nno\n 0: no /.*$/m borfle\nbib.gif\nno\n 0: borfle /.*$/s borfle\nbib.gif\nno\n 0: borfle\x0abib.gif\x0ano\x0a /.*$/ms borfle\nbib.gif\nno\n 0: borfle\x0abib.gif\x0ano\x0a /(.*X|^B)/ abcde\n1234Xyz 0: 1234X 1: 1234X BarFoo 0: B 1: B *** Failers No match abcde\nBar No match /(.*X|^B)/m abcde\n1234Xyz 0: 1234X 1: 1234X BarFoo 0: B 1: B abcde\nBar 0: B 1: B /(.*X|^B)/s abcde\n1234Xyz 0: abcde\x0a1234X 1: abcde\x0a1234X BarFoo 0: B 1: B *** Failers No match abcde\nBar No match /(.*X|^B)/ms abcde\n1234Xyz 0: abcde\x0a1234X 1: abcde\x0a1234X BarFoo 0: B 1: B abcde\nBar 0: B 1: B /(?s)(.*X|^B)/ abcde\n1234Xyz 0: abcde\x0a1234X 1: abcde\x0a1234X BarFoo 0: B 1: B *** Failers No match abcde\nBar No match /(?s:.*X|^B)/ abcde\n1234Xyz 0: abcde\x0a1234X BarFoo 0: B *** Failers No match abcde\nBar No match /^.*B/ **** Failers No match abc\nB No match /(?s)^.*B/ abc\nB 0: abc\x0aB /(?m)^.*B/ abc\nB 0: B /(?ms)^.*B/ abc\nB 0: abc\x0aB /(?ms)^B/ abc\nB 0: B /(?s)B$/ B\n 0: B /^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ 123456654321 0: 123456654321 /^\d\d\d\d\d\d\d\d\d\d\d\d/ 123456654321 0: 123456654321 /^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ 123456654321 0: 123456654321 /^[abc]{12}/ abcabcabcabc 0: abcabcabcabc /^[a-c]{12}/ abcabcabcabc 0: abcabcabcabc /^(a|b|c){12}/ abcabcabcabc 0: abcabcabcabc 1: c /^[abcdefghijklmnopqrstuvwxy0123456789]/ n 0: n *** Failers No match z No match /abcde{0,0}/ abcd 0: abcd *** Failers No match abce No match /ab[cd]{0,0}e/ abe 0: abe *** Failers No match abcde No match /ab(c){0,0}d/ abd 0: abd *** Failers No match abcd No match /a(b*)/ a 0: a 1: ab 0: ab 1: b abbbb 0: abbbb 1: bbbb *** Failers 0: a 1: bbbbb No match /ab\d{0}e/ abe 0: abe *** Failers No match ab1e No match /"([^\\"]+|\\.)*"/ the \"quick\" brown fox 0: "quick" 1: quick \"the \\\"quick\\\" brown fox\" 0: "the \"quick\" brown fox" 1: brown fox /.*?/g+ abc 0: 0+ abc 0: a 0+ bc 0: 0+ bc 0: b 0+ c 0: 0+ c 0: c 0+ 0: 0+ /\b/g+ abc 0: 0+ abc 0: 0+ /\b/+g abc 0: 0+ abc 0: 0+ //g abc 0: 0: 0: 0: /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide 0: 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide 1: BGCOLOR='#DBE9E9' 2: align=left valign=top 3: 43. 4: Word Processor
(N-1286) 5: 6: 7: 8: align=left valign=top 9: Lega lstaff.com 10: align=left valign=top 11: CA - Statewide /a[^a]b/ acb 0: acb a\nb 0: a\x0ab /a.b/ acb 0: acb *** Failers No match a\nb No match /a[^a]b/s acb 0: acb a\nb 0: a\x0ab /a.b/s acb 0: acb a\nb 0: a\x0ab /^(b+?|a){1,2}?c/ bac 0: bac 1: a bbac 0: bbac 1: a bbbac 0: bbbac 1: a bbbbac 0: bbbbac 1: a bbbbbac 0: bbbbbac 1: a /^(b+|a){1,2}?c/ bac 0: bac 1: a bbac 0: bbac 1: a bbbac 0: bbbac 1: a bbbbac 0: bbbbac 1: a bbbbbac 0: bbbbbac 1: a /(?!\A)x/m x\nb\n No match a\bx\n 0: x /\x0{ab}/ \0{ab} 0: \x00{ab} /(A|B)*?CD/ CD 0: CD /(A|B)*CD/ CD 0: CD /(AB)*?\1/ ABABAB 0: ABAB 1: AB /(AB)*\1/ ABABAB 0: ABABAB 1: AB /(?.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ No match "(?>.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo /(?>(\.\d\d[1-9]?))\d+/ 1.230003938 0: .230003938 1: .23 1.875000282 0: .875000282 1: .875 *** Failers No match 1.235 No match /^((?>\w+)|(?>\s+))*$/ now is the time for all good men to come to the aid of the party 0: now is the time for all good men to come to the aid of the party 1: party *** Failers No match this is not a line with only words and spaces! No match /(\d+)(\w)/ 12345a 0: 12345a 1: 12345 2: a 12345+ 0: 12345 1: 1234 2: 5 /((?>\d+))(\w)/ 12345a 0: 12345a 1: 12345 2: a *** Failers No match 12345+ No match /(?>a+)b/ aaab 0: aaab /((?>a+)b)/ aaab 0: aaab 1: aaab /(?>(a+))b/ aaab 0: aaab 1: aaa /(?>b)+/ aaabbbccc 0: bbb /(?>a+|b+|c+)*c/ aaabbbbccccd 0: aaabbbbc /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: x /\(((?>[^()]+)|\([^()]+\))+\)/ (abc) 0: (abc) 1: abc (abc(def)xyz) 0: (abc(def)xyz) 1: xyz *** Failers No match ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /a(?-i)b/i ab 0: ab Ab 0: Ab *** Failers No match aB No match AB No match /(a (?x)b c)d e/ a bcd e 0: a bcd e 1: a bc *** Failers No match a b cd e No match abcd e No match a bcde No match /(a b(?x)c d (?-x)e f)/ a bcde f 0: a bcde f 1: a bcde f *** Failers No match abcdef No match /(a(?i)b)c/ abc 0: abc 1: ab aBc 0: aBc 1: aB *** Failers No match abC No match aBC No match Abc No match ABc No match ABC No match AbC No match /a(?i:b)c/ abc 0: abc aBc 0: aBc *** Failers No match ABC No match abC No match aBC No match /a(?i:b)*c/ aBc 0: aBc aBBc 0: aBBc *** Failers No match aBC No match aBBC No match /a(?=b(?i)c)\w\wd/ abcd 0: abcd abCd 0: abCd *** Failers No match aBCd No match abcD No match /(?s-i:more.*than).*million/i more than million 0: more than million more than MILLION 0: more than MILLION more \n than Million 0: more \x0a than Million *** Failers No match MORE THAN MILLION No match more \n than \n million No match /(?:(?s-i)more.*than).*million/i more than million 0: more than million more than MILLION 0: more than MILLION more \n than Million 0: more \x0a than Million *** Failers No match MORE THAN MILLION No match more \n than \n million No match /(?>a(?i)b+)+c/ abc 0: abc aBbc 0: aBbc aBBc 0: aBBc *** Failers No match Abc No match abAb No match abbC No match /(?=a(?i)b)\w\wc/ abc 0: abc aBc 0: aBc *** Failers No match Ab No match abC No match aBC No match /(?<=a(?i)b)(\w\w)c/ abxxc 0: xxc 1: xx aBxxc 0: xxc 1: xx *** Failers No match Abxxc No match ABxxc No match abxxC No match /(?:(a)|b)(?(1)A|B)/ aA 0: aA 1: a bB 0: bB *** Failers No match aB No match bA No match /^(a)?(?(1)a|b)+$/ aa 0: aa 1: a b 0: b bb 0: bb *** Failers No match ab No match /^(?(?=abc)\w{3}:|\d\d)$/ abc: 0: abc: 12 0: 12 *** Failers No match 123 No match xyz No match /^(?(?!abc)\d\d|\w{3}:)$/ abc: 0: abc: 12 0: 12 *** Failers No match 123 No match xyz No match /(?(?<=foo)bar|cat)/ foobar 0: bar cat 0: cat fcat 0: cat focat 0: cat *** Failers No match foocat No match /(?(?a*)*/ a 0: a aa 0: aa aaaa 0: aaaa /(abc|)+/ abc 0: abc 1: abcabc 0: abcabc 1: abcabcabc 0: abcabcabc 1: xyz 0: 1: /([a]*)*/ a 0: a 1: aaaaa 0: aaaaa 1: /([ab]*)*/ a 0: a 1: b 0: b 1: ababab 0: ababab 1: aaaabcde 0: aaaab 1: bbbb 0: bbbb 1: /([^a]*)*/ b 0: b 1: bbbb 0: bbbb 1: aaa 0: 1: /([^ab]*)*/ cccc 0: cccc 1: abab 0: 1: /([a]*?)*/ a 0: 1: aaaa 0: 1: /([ab]*?)*/ a 0: 1: b 0: 1: abab 0: 1: baba 0: 1: /([^a]*?)*/ b 0: 1: bbbb 0: 1: aaa 0: 1: /([^ab]*?)*/ c 0: 1: cccc 0: 1: baba 0: 1: /(?>a*)*/ a 0: a aaabcde 0: aaa /((?>a*))*/ aaaaa 0: aaaaa 1: aabbaa 0: aa 1: /((?>a*?))*/ aaaaa 0: 1: aabbaa 0: 1: /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x 12-sep-98 0: 12-sep-98 12-09-98 0: 12-09-98 *** Failers No match sep-12-98 No match /(?<=(foo))bar\1/ foobarfoo 0: barfoo 1: foo foobarfootling 0: barfoo 1: foo *** Failers No match foobar No match barfoo No match /(?i:saturday|sunday)/ saturday 0: saturday sunday 0: sunday Saturday 0: Saturday Sunday 0: Sunday SATURDAY 0: SATURDAY SUNDAY 0: SUNDAY SunDay 0: SunDay /(a(?i)bc|BB)x/ abcx 0: abcx 1: abc aBCx 0: aBCx 1: aBC bbx 0: bbx 1: bb BBx 0: BBx 1: BB *** Failers No match abcX No match aBCX No match bbX No match BBX No match /^([ab](?i)[cd]|[ef])/ ac 0: ac 1: ac aC 0: aC 1: aC bD 0: bD 1: bD elephant 0: e 1: e Europe 0: E 1: E frog 0: f 1: f France 0: F 1: F *** Failers No match Africa No match /^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ ab 0: ab 1: ab aBd 0: aBd 1: aBd xy 0: xy 1: xy xY 0: xY 1: xY zebra 0: z 1: z Zambesi 0: Z 1: Z *** Failers No match aCD No match XY No match /(?<=foo\n)^bar/m foo\nbar 0: bar *** Failers No match bar No match baz\nbar No match /(?<=(?]&/ <&OUT 0: <& /^(a\1?){4}$/ aaaaaaaaaa 0: aaaaaaaaaa 1: aaaa *** Failers No match AB No match aaaaaaaaa No match aaaaaaaaaaa No match /^(a(?(1)\1)){4}$/ aaaaaaaaaa 0: aaaaaaaaaa 1: aaaa *** Failers No match aaaaaaaaa No match aaaaaaaaaaa No match /(?:(f)(o)(o)|(b)(a)(r))*/ foobar 0: foobar 1: f 2: o 3: o 4: b 5: a 6: r /(?<=a)b/ ab 0: b *** Failers No match cb No match b No match /(? 2: abcd xy:z:::abcd 0: xy:z:::abcd 1: xy:z::: 2: abcd /^[^bcd]*(c+)/ aexycd 0: aexyc 1: c /(a*)b+/ caab 0: aab 1: aa /([\w:]+::)?(\w+)$/ abcd 0: abcd 1: 2: abcd xy:z:::abcd 0: xy:z:::abcd 1: xy:z::: 2: abcd *** Failers 0: Failers 1: 2: Failers abcd: No match abcd: No match /^[^bcd]*(c+)/ aexycd 0: aexyc 1: c /(>a+)ab/ /(?>a+)b/ aaab 0: aaab /([[:]+)/ a:[b]: 0: :[ 1: :[ /([[=]+)/ a=[b]= 0: =[ 1: =[ /([[.]+)/ a.[b]. 0: .[ 1: .[ /((?>a+)b)/ aaab 0: aaab 1: aaab /(?>(a+))b/ aaab 0: aaab 1: aaa /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: x /a\Z/ *** Failers No match aaab No match a\nb\n No match /b\Z/ a\nb\n 0: b /b\z/ /b\Z/ a\nb 0: b /b\z/ a\nb 0: b *** Failers No match /^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ a 0: a 1: abc 0: abc 1: a-b 0: a-b 1: 0-9 0: 0-9 1: a.b 0: a.b 1: 5.6.7 0: 5.6.7 1: the.quick.brown.fox 0: the.quick.brown.fox 1: a100.b200.300c 0: a100.b200.300c 1: 12-ab.1245 0: 12-ab.1245 1: *** Failers No match \ No match .a No match -a No match a- No match a. No match a_b No match a.- No match a.. No match ab..bc No match the.quick.brown.fox- No match the.quick.brown.fox. No match the.quick.brown.fox_ No match the.quick.brown.fox+ No match /(?>.*)(?<=(abcd|wxyz))/ alphabetabcd 0: alphabetabcd 1: abcd endingwxyz 0: endingwxyz 1: wxyz *** Failers No match a rather long string that doesn't end with one of them No match /word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark No match /word (?>[a-zA-Z0-9]+ ){0,30}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match /(?<=\d{3}(?!999))foo/ 999foo 0: foo 123999foo 0: foo *** Failers No match 123abcfoo No match /(?<=(?!...999)\d{3})foo/ 999foo 0: foo 123999foo 0: foo *** Failers No match 123abcfoo No match /(?<=\d{3}(?!999)...)foo/ 123abcfoo 0: foo 123456foo 0: foo *** Failers No match 123999foo No match /(?<=\d{3}...)(? 2: 3: abcd
2: 3: abcd \s*)=(?>\s*) # find 2: 3: abcd Z)+|A)*/ ZABCDEFG 0: ZA 1: A /((?>)+|A)*/ ZABCDEFG 0: 1: /a*/g abbab 0: a 0: 0: 0: a 0: 0: /^[a-\d]/ abcde 0: a -things 0: - 0digit 0: 0 *** Failers No match bcdef No match /^[\d-a]/ abcde 0: a -things 0: - 0digit 0: 0 *** Failers No match bcdef No match /[[:space:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d\x0b /[[:blank:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09 /[\s]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d /\s+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d /a b/x ab No match /(?!\A)x/m a\nxb\n 0: x /(?!^)x/m a\nxb\n No match /abc\Qabc\Eabc/ abcabcabc 0: abcabcabc /abc\Q(*+|\Eabc/ abc(*+|abc 0: abc(*+|abc / abc\Q abc\Eabc/x abc abcabc 0: abc abcabc *** Failers No match abcabcabc No match /abc#comment \Q#not comment literal\E/x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal/x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal\E #more comment /x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal\E #more comment/x abc#not comment\n literal 0: abc#not comment\x0a literal /\Qabc\$xyz\E/ abc\\\$xyz 0: abc\$xyz /\Qabc\E\$\Qxyz\E/ abc\$xyz 0: abc$xyz /\Gabc/ abc 0: abc *** Failers No match xyzabc No match /\Gabc./g abc1abc2xyzabc3 0: abc1 0: abc2 /abc./g abc1abc2xyzabc3 0: abc1 0: abc2 0: abc3 /a(?x: b c )d/ XabcdY 0: abcd *** Failers No match Xa b c d Y No match /((?x)x y z | a b c)/ XabcY 0: abc 1: abc AxyzB 0: xyz 1: xyz /(?i)AB(?-i)C/ XabCY 0: abC *** Failers No match XabcY No match /((?i)AB(?-i)C|D)E/ abCE 0: abCE 1: abC DE 0: DE 1: D *** Failers No match abcE No match abCe No match dE No match De No match /(.*)\d+\1/ abc123abc 0: abc123abc 1: abc abc123bc 0: bc123bc 1: bc /(.*)\d+\1/s abc123abc 0: abc123abc 1: abc abc123bc 0: bc123bc 1: bc /((.*))\d+\1/ abc123abc 0: abc123abc 1: abc 2: abc abc123bc 0: bc123bc 1: bc 2: bc /-- This tests for an IPv6 address in the form where it can have up to --/ /-- eight components, one and only one of which is empty. This must be --/ No match /-- an internal component. --/ No match /^(?!:) # colon disallowed at start (?: # start of item (?: [0-9a-f]{1,4} | # 1-4 hex digits or (?(1)0 | () ) ) # if null previously matched, fail; else null : # followed by colon ){1,7} # end item; 1-7 of them required [0-9a-f]{1,4} $ # final hex number at end of string (?(1)|.) # check that there was an empty component /xi a123::a123 0: a123::a123 1: a123:b342::abcd 0: a123:b342::abcd 1: a123:b342::324e:abcd 0: a123:b342::324e:abcd 1: a123:ddde:b342::324e:abcd 0: a123:ddde:b342::324e:abcd 1: a123:ddde:b342::324e:dcba:abcd 0: a123:ddde:b342::324e:dcba:abcd 1: a123:ddde:9999:b342::324e:dcba:abcd 0: a123:ddde:9999:b342::324e:dcba:abcd 1: *** Failers No match 1:2:3:4:5:6:7:8 No match a123:bce:ddde:9999:b342::324e:dcba:abcd No match a123::9999:b342::324e:dcba:abcd No match abcde:2:3:4:5:6:7:8 No match ::1 No match abcd:fee0:123:: No match :1 No match 1: No match /[z\Qa-d]\E]/ z 0: z a 0: a - 0: - d 0: d ] 0: ] *** Failers 0: a b No match /[\z\C]/ z 0: z C 0: C /\M/ M 0: M /(a+)*b/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /(?i)reg(?:ul(?:[aä]|ae)r|ex)/ REGular 0: REGular regulaer 0: regulaer Regex 0: Regex regulär 0: regul\xe4r /Åæåä[à-ÿÀ-ß]+/ Åæåäà 0: \xc5\xe6\xe5\xe4\xe0 Åæåäÿ 0: \xc5\xe6\xe5\xe4\xff ÅæåäÀ 0: \xc5\xe6\xe5\xe4\xc0 Åæåäß 0: \xc5\xe6\xe5\xe4\xdf /(?<=Z)X./ \x84XAZXB 0: XB /ab cd (?x) de fg/ ab cd defg 0: ab cd defg /ab cd(?x) de fg/ ab cddefg 0: ab cddefg ** Failers No match abcddefg No match /(? 2: D 0: D 1: 2: /(a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 1: /(?>a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /(?:a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /\Z/g abc\n 0: 0: /^(?s)(?>.*)(? 2: a /(?>(a))b|(a)c/ ac 0: ac 1: 2: a /(?=(a))ab|(a)c/ ac 0: ac 1: 2: a /((?>(a))b|(a)c)/ ac 0: ac 1: ac 2: 3: a /((?>(a))b|(a)c)++/ ac 0: ac 1: ac 2: 3: a /(?:(?>(a))b|(a)c)++/ ac 0: ac 1: 2: a /(?=(?>(a))b|(a)c)(..)/ ac 0: ac 1: 2: a 3: ac /(?>(?>(a))b|(a)c)/ ac 0: ac 1: 2: a /(?:(?>([ab])))+a=/+ =ba= 0: ba= 0+ 1: b /(?>([ab]))+a=/+ =ba= 0: ba= 0+ 1: b /((?>(a+)b)+(aabab))/ aaaabaaabaabab 0: aaaabaaabaabab 1: aaaabaaabaabab 2: aaa 3: aabab /(?>a+|ab)+?c/ aabc No match /(?>a+|ab)+c/ aabc No match /(?:a+|ab)+c/ aabc 0: aabc /(?(?=(a))a)/ a 0: a 1: a /(?(?=(a))a)(b)/ ab 0: ab 1: a 2: b /^(?:a|ab)++c/ aaaabc No match /^(?>a|ab)++c/ aaaabc No match /^(?:a|ab)+c/ aaaabc 0: aaaabc /(?=abc){3}abc/+ abcabcabc 0: abc 0+ abcabc ** Failers No match xyz No match /(?=abc)+abc/+ abcabcabc 0: abc 0+ abcabc ** Failers No match xyz No match /(?=abc)++abc/+ abcabcabc 0: abc 0+ abcabc ** Failers No match xyz No match /(?=abc){0}xyz/ xyz 0: xyz /(?=abc){1}xyz/ ** Failers No match xyz No match /(?=(a))?./ ab 0: a 1: a bc 0: b /(?=(a))??./ ab 0: a bc 0: b /^(?=(a)){0}b(?1)/ backgammon 0: ba /^(?=(?1))?[az]([abc])d/ abd 0: abd 1: b zcdxx 0: zcd 1: c /^(?!a){0}\w+/ aaaaa 0: aaaaa /(?<=(abc))?xyz/ abcxyz 0: xyz 1: abc pqrxyz 0: xyz /^[\g]+/ ggg<<>> 0: ggg<<>> ** Failers No match \\ga No match /^[\ga]+/ gggagagaxyz 0: gggagaga /^[:a[:digit:]]+/ aaaa444:::Z 0: aaaa444::: /^[:a[:digit:]:b]+/ aaaa444:::bbbZ 0: aaaa444:::bbb /[:a]xxx[b:]/ :xxx: 0: :xxx: /(?<=a{2})b/i xaabc 0: b ** Failers No match xabc No match /(?XNNNYZ 0: XNNNYZ > X NYQZ 0: X NYQZ ** Failers No match >XYZ No match > X NY Z No match /\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ >XY\x0aZ\x0aA\x0bNN\x0c 0: XY\x0aZ\x0aA\x0bNN\x0c >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c /(foo)\Kbar/ foobar 0: bar 1: foo /(foo)(\Kbar|baz)/ foobar 0: bar 1: foo 2: bar foobaz 0: foobaz 1: foo 2: baz /(foo\Kbar)baz/ foobarbaz 0: barbaz 1: foobar /abc\K|def\K/g+ Xabcdefghi 0: 0+ defghi 0: 0+ ghi /ab\Kc|de\Kf/g+ Xabcdefghi 0: c 0+ defghi 0: f 0+ ghi /(?=C)/g+ ABCDECBA 0: 0+ CDECBA 0: 0+ CBA /^abc\K/+ abcdef 0: 0+ def ** Failers No match defabcxyz No match /^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ ababababbbabZXXXX 0: ababababbbabZ 1: ab 2: b /(?tom|bon)-\g{A}/ tom-tom 0: tom-tom 1: tom bon-bon 0: bon-bon 1: bon /(^(a|b\g{-1}))/ bacxxx No match /(?|(abc)|(xyz))\1/ abcabc 0: abcabc 1: abc xyzxyz 0: xyzxyz 1: xyz ** Failers No match abcxyz No match xyzabc No match /(?|(abc)|(xyz))(?1)/ abcabc 0: abcabc 1: abc xyzabc 0: xyzabc 1: xyz ** Failers No match xyzxyz No match /^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ XYabcdY 0: XYabcdY 1: a 2: b 3: c 4: d 5: Y /^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ XYabcdY 0: XYabcdY 1: a 2: b 3: 4: 5: c 6: d 7: Y /^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ XYabcdY 0: XYabcdY 1: a 2: b 3: 4: 5: c 6: d 7: Y /(?'abc'\w+):\k{2}/ a:aaxyz 0: a:aa 1: a ab:ababxyz 0: ab:abab 1: ab ** Failers No match a:axyz No match ab:abxyz No match /(?'abc'\w+):\g{abc}{2}/ a:aaxyz 0: a:aa 1: a ab:ababxyz 0: ab:abab 1: ab ** Failers No match a:axyz No match ab:abxyz No match /^(?a)? (?()b|c) (?('ab')d|e)/x abd 0: abd 1: a ce 0: ce /^(a.)\g-1Z/ aXaXZ 0: aXaXZ 1: aX /^(a.)\g{-1}Z/ aXaXZ 0: aXaXZ 1: aX /^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x abcd 0: ab /(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) (?(DEFINE) (?[a-z]+) (?\d+) )/x metcalfe 33 0: metcalfe 33 1: metcalfe 2: 33 /(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ 1.2.3.4 0: 1.2.3.4 1: 2: .4 131.111.10.206 0: 131.111.10.206 1: 2: .206 10.0.0.0 0: 10.0.0.0 1: 2: .0 ** Failers No match 10.6 No match 455.3.4.5 No match /\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ 1.2.3.4 0: 1.2.3.4 1: .4 131.111.10.206 0: 131.111.10.206 1: .206 10.0.0.0 0: 10.0.0.0 1: .0 ** Failers No match 10.6 No match 455.3.4.5 No match /^(\w++|\s++)*$/ now is the time for all good men to come to the aid of the party 0: now is the time for all good men to come to the aid of the party 1: party *** Failers No match this is not a line with only words and spaces! No match /(\d++)(\w)/ 12345a 0: 12345a 1: 12345 2: a *** Failers No match 12345+ No match /a++b/ aaab 0: aaab /(a++b)/ aaab 0: aaab 1: aaab /(a++)b/ aaab 0: aaab 1: aaa /([^()]++|\([^()]*\))+/ ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: x /\(([^()]++|\([^()]+\))+\)/ (abc) 0: (abc) 1: abc (abc(def)xyz) 0: (abc(def)xyz) 1: xyz *** Failers No match ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /^([^()]|\((?1)*\))*$/ abc 0: abc 1: c a(b)c 0: a(b)c 1: c a(b(c))d 0: a(b(c))d 1: d *** Failers) No match a(b(c)d No match /^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3) 2: 3: Satanoscillatemymetallicsonatas 4: S AmanaplanacanalPanama 0: AmanaplanacanalPanama 1: 2: 3: AmanaplanacanalPanama 4: A AblewasIereIsawElba 0: AblewasIereIsawElba 1: 2: 3: AblewasIereIsawElba 4: A *** Failers No match Thequickbrownfox No match /^(\d+|\((?1)([+*-])(?1)\)|-(?1))$/ 12 0: 12 1: 12 (((2+2)*-3)-7) 0: (((2+2)*-3)-7) 1: (((2+2)*-3)-7) 2: - -12 0: -12 1: -12 *** Failers No match ((2+2)*-3)-7) No match /^(x(y|(?1){2})z)/ xyz 0: xyz 1: xyz 2: y xxyzxyzz 0: xxyzxyzz 1: xxyzxyzz 2: xyzxyz *** Failers No match xxyzz No match xxyzxyzxyzz No match /((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))/x <> 0: <> 1: <> 2: <> 0: 1: 2: hij> 0: hij> 1: hij> 2: hij> hij> 0: 1: 2: def> 0: def> 1: def> 2: def> 0: <> 1: <> 2: <> *** Failers No match 2: 3: Satan, oscillate my metallic sonatas 4: S A man, a plan, a canal: Panama! 0: A man, a plan, a canal: Panama! 1: 2: 3: A man, a plan, a canal: Panama 4: A Able was I ere I saw Elba. 0: Able was I ere I saw Elba. 1: 2: 3: Able was I ere I saw Elba 4: A *** Failers No match The quick brown fox No match /^((.)(?1)\2|.)$/ a 0: a 1: a aba 0: aba 1: aba 2: a aabaa 0: aabaa 1: aabaa 2: a abcdcba 0: abcdcba 1: abcdcba 2: a pqaabaaqp 0: pqaabaaqp 1: pqaabaaqp 2: p ablewasiereisawelba 0: ablewasiereisawelba 1: ablewasiereisawelba 2: a rhubarb No match the quick brown fox No match /(a)(?<=b(?1))/ baz 0: a 1: a ** Failers No match caz No match /(?<=b(?1))(a)/ zbaaz 0: a 1: a ** Failers No match aaa No match /(?a)(?<=b(?&X))/ baz 0: a 1: a /^(?|(abc)|(def))\1/ abcabc 0: abcabc 1: abc defdef 0: defdef 1: def ** Failers No match abcdef No match defabc No match /^(?|(abc)|(def))(?1)/ abcabc 0: abcabc 1: abc defabc 0: defabc 1: def ** Failers No match defdef No match abcdef No match /(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ a\"aaaaa 0: a"aaaaa 1: " 2: 3: " b\"aaaaa 0: b"aaaaa 1: 2: 3: 4: " 5: 6: " ** Failers No match b\"11111 No match /(?:(?1)|B)(A(*F)|C)/ ABCD 0: BC 1: C CCD 0: CC 1: C ** Failers No match CAD No match /^(?:(?1)|B)(A(*F)|C)/ CCD 0: CC 1: C BCD 0: BC 1: C ** Failers No match ABCD No match CAD No match BAD No match /(?:(?1)|B)(A(*ACCEPT)XX|C)D/ AAD 0: AA 1: A ACD 0: ACD 1: C BAD 0: BA 1: A BCD 0: BCD 1: C BAX 0: BA 1: A ** Failers No match ACX No match ABC No match /(?(DEFINE)(A))B(?1)C/ BAC 0: BAC /(?(DEFINE)((A)\2))B(?1)C/ BAAC 0: BAAC /(? \( ( [^()]++ | (?&pn) )* \) )/x (ab(cd)ef) 0: (ab(cd)ef) 1: (ab(cd)ef) 2: ef /^(?!a(*SKIP)b)/ ac 0: /^(?=a(*SKIP)b|ac)/ ** Failers No match ac No match /^(?=a(*THEN)b|ac)/ ac 0: /^(?=a(*PRUNE)b)/ ab 0: ** Failers No match ac No match /^(?=a(*ACCEPT)b)/ ac 0: /^(?(?!a(*SKIP)b))/ ac 0: /(?>a\Kb)/ ab 0: b /((?>a\Kb))/ ab 0: b 1: ab /(a\Kb)/ ab 0: b 1: ab /^a\Kcz|ac/ ac 0: ac /(?>a\Kbz|ab)/ ab 0: ab /^(?&t)(?(DEFINE)(?a\Kb))$/ ab 0: b /^([^()]|\((?1)*\))*$/ a(b)c 0: a(b)c 1: c a(b(c)d)e 0: a(b(c)d)e 1: e /(?P(?P0)(?P>L1)|(?P>L2))/ 0 0: 0 1: 0 00 0: 00 1: 00 2: 0 0000 0: 0000 1: 0000 2: 0 /(?P(?P0)|(?P>L2)(?P>L1))/ 0 0: 0 1: 0 2: 0 00 0: 0 1: 0 2: 0 0000 0: 0 1: 0 2: 0 /--- This one does fail, as expected, in Perl. It needs the complex item at the end of the pattern. A single letter instead of (B|D) makes it not fail, which I think is a Perl bug. --- / /A(*COMMIT)(B|D)/ ACABX No match /--- Check the use of names for failure ---/ /^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K ** Failers No match AC No match, mark = A CB No match, mark = B /--- Force no study, otherwise mark is not seen. The studied version is in test 2 because it isn't Perl-compatible. ---/ /(*MARK:A)(*SKIP:B)(C|X)/KSS C 0: C 1: C MK: A D No match, mark = A /^(A(*THEN:A)B|C(*THEN:B)D)/K ** Failers No match CB No match, mark = B /^(?:A(*THEN:A)B|C(*THEN:B)D)/K CB No match, mark = B /^(?>A(*THEN:A)B|C(*THEN:B)D)/K CB No match, mark = B /--- This should succeed, as the skip causes bump to offset 1 (the mark). Note that we have to have something complicated such as (B|Z) at the end because, for Perl, a simple character somehow causes an unwanted optimization to mess with the handling of backtracking verbs. ---/ /A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC 0: AC /--- Test skipping over a non-matching mark. ---/ /A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK AAAC 0: AC /--- Check shorthand for MARK ---/ /A(*:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC 0: AC /--- Don't loop! Force no study, otherwise mark is not seen. ---/ /(*:A)A+(*SKIP:A)(B|Z)/KSS AAAC No match, mark = A /--- This should succeed, as a non-existent skip name disables the skip ---/ /A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK AAAC 0: AC /A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK AAAC 0: AC MK: B /--- COMMIT at the start of a pattern should act like an anchor. Again, however, we need the complication for Perl. ---/ /(*COMMIT)(A|P)(B|P)(C|P)/ ABCDEFG 0: ABC 1: A 2: B 3: C ** Failers No match DEFGABC No match /--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ /(\w+)(?>b(*COMMIT))\w{2}/ abbb 0: abbb 1: a /(\w+)b(*COMMIT)\w{2}/ abbb No match /--- Check opening parens in comment when seeking forward reference. ---/ /(?&t)(?#()(?(DEFINE)(?a))/ bac 0: a /--- COMMIT should override THEN ---/ /(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ yes No match /(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ yes No match /b?(*SKIP)c/ bc 0: bc abc 0: bc /(*SKIP)bc/ a No match /(*SKIP)b/ a No match /(?P(?P=abn)xxx|)+/ xxx 0: 1: /(?i:([^b]))(?1)/ aa 0: aa 1: a aA 0: aA 1: a ** Failers 0: ** 1: * ab No match aB No match Ba No match ba No match /^(?&t)*+(?(DEFINE)(?a))\w$/ aaaaaaX 0: aaaaaaX ** Failers No match aaaaaa No match /^(?&t)*(?(DEFINE)(?a))\w$/ aaaaaaX 0: aaaaaaX aaaaaa 0: aaaaaa /^(a)*+(\w)/ aaaaX 0: aaaaX 1: a 2: X YZ 0: Y 1: 2: Y ** Failers No match aaaa No match /^(?:a)*+(\w)/ aaaaX 0: aaaaX 1: X YZ 0: Y 1: Y ** Failers No match aaaa No match /^(a)++(\w)/ aaaaX 0: aaaaX 1: a 2: X ** Failers No match aaaa No match YZ No match /^(?:a)++(\w)/ aaaaX 0: aaaaX 1: X ** Failers No match aaaa No match YZ No match /^(a)?+(\w)/ aaaaX 0: aa 1: a 2: a YZ 0: Y 1: 2: Y /^(?:a)?+(\w)/ aaaaX 0: aa 1: a YZ 0: Y 1: Y /^(a){2,}+(\w)/ aaaaX 0: aaaaX 1: a 2: X ** Failers No match aaa No match YZ No match /^(?:a){2,}+(\w)/ aaaaX 0: aaaaX 1: X ** Failers No match aaa No match YZ No match /(a|)*(?1)b/ b 0: b 1: ab 0: ab 1: aab 0: aab 1: /(a)++(?1)b/ ** Failers No match ab No match aab No match /(a)*+(?1)b/ ** Failers No match ab No match aab No match /(?1)(?:(b)){0}/ b 0: b /(foo ( \( ((?:(?> [^()]+ )|(?2))*) \) ) )/x foo(bar(baz)+baz(bop)) 0: foo(bar(baz)+baz(bop)) 1: foo(bar(baz)+baz(bop)) 2: (bar(baz)+baz(bop)) 3: bar(baz)+baz(bop) /(A (A|B(*ACCEPT)|C) D)(E)/x AB 0: AB 1: AB 2: B /\A.*?(?:a|b(*THEN)c)/ ba 0: ba /\A.*?(?:a|bc)/ ba 0: ba /\A.*?(a|b(*THEN)c)/ ba 0: ba 1: a /\A.*?(a|bc)/ ba 0: ba 1: a /\A.*?(?:a|b(*THEN)c)++/ ba 0: ba /\A.*?(?:a|bc)++/ ba 0: ba /\A.*?(a|b(*THEN)c)++/ ba 0: ba 1: a /\A.*?(a|bc)++/ ba 0: ba 1: a /\A.*?(?:a|b(*THEN)c|d)/ ba 0: ba /\A.*?(?:a|bc|d)/ ba 0: ba /(?:(b))++/ beetle 0: b 1: b /(?(?=(a(*ACCEPT)z))a)/ a 0: a 1: a /^(a)(?1)+ab/ aaaab 0: aaaab 1: a /^(a)(?1)++ab/ aaaab No match /^(?=a(*:M))aZ/K aZbc 0: aZ MK: M /^(?!(*:M)b)aZ/K aZbc 0: aZ /(?(DEFINE)(a))?b(?1)/ backgammon 0: ba /^\N+/ abc\ndef 0: abc /^\N{1,}/ abc\ndef 0: abc /(?(R)a+|(?R)b)/ aaaabcde 0: aaaab /(?(R)a+|((?R))b)/ aaaabcde 0: aaaab 1: aaaa /((?(R)a+|(?1)b))/ aaaabcde 0: aaaab 1: aaaab /((?(R1)a+|(?1)b))/ aaaabcde 0: aaaab 1: aaaab /a(*:any name)/K abc 0: a MK: any \x0aname /(?>(?&t)c|(?&t))(?(DEFINE)(?a|b(*PRUNE)c))/ a 0: a ba 0: a bba 0: a /--- Checking revised (*THEN) handling ---/ /--- Capture ---/ /^.*? (a(*THEN)b) c/x aabc No match /^.*? (a(*THEN)b|(*F)) c/x aabc 0: aabc 1: ab /^.*? ( (a(*THEN)b) | (*F) ) c/x aabc 0: aabc 1: ab 2: ab /^.*? ( (a(*THEN)b) ) c/x aabc No match /--- Non-capture ---/ /^.*? (?:a(*THEN)b) c/x aabc No match /^.*? (?:a(*THEN)b|(*F)) c/x aabc 0: aabc /^.*? (?: (?:a(*THEN)b) | (*F) ) c/x aabc 0: aabc /^.*? (?: (?:a(*THEN)b) ) c/x aabc No match /--- Atomic ---/ /^.*? (?>a(*THEN)b) c/x aabc No match /^.*? (?>a(*THEN)b|(*F)) c/x aabc 0: aabc /^.*? (?> (?>a(*THEN)b) | (*F) ) c/x aabc 0: aabc /^.*? (?> (?>a(*THEN)b) ) c/x aabc No match /--- Possessive capture ---/ /^.*? (a(*THEN)b)++ c/x aabc No match /^.*? (a(*THEN)b|(*F))++ c/x aabc 0: aabc 1: ab /^.*? ( (a(*THEN)b)++ | (*F) )++ c/x aabc 0: aabc 1: ab 2: ab /^.*? ( (a(*THEN)b)++ )++ c/x aabc No match /--- Possessive non-capture ---/ /^.*? (?:a(*THEN)b)++ c/x aabc No match /^.*? (?:a(*THEN)b|(*F))++ c/x aabc 0: aabc /^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c/x aabc 0: aabc /^.*? (?: (?:a(*THEN)b)++ )++ c/x aabc No match /--- Condition assertion ---/ /^(?(?=a(*THEN)b)ab|ac)/ ac 0: ac /--- Condition ---/ /^.*?(?(?=a)a|b(*THEN)c)/ ba No match /^.*?(?:(?(?=a)a|b(*THEN)c)|d)/ ba 0: ba /^.*?(?(?=a)a(*THEN)b|c)/ ac No match /--- Assertion ---/ /^.*(?=a(*THEN)b)/ aabc 0: a /------------------------------/ /(?>a(*:m))/imsxSK a 0: a MK: m /(?>(a)(*:m))/imsxSK a 0: a 1: a MK: m /(?<=a(*ACCEPT)b)c/ xacd 0: c /(?<=(a(*ACCEPT)b))c/ xacd 0: c 1: a /(?<=(a(*COMMIT)b))c/ xabcd 0: c 1: ab ** Failers No match xacd No match /(? 2: /(another)?(\1+)test/ hello world test No match /(a(*COMMIT)b){0}a(?1)|aac/ aac 0: aac /(?!a(*COMMIT)b)ac|cd/ ac 0: ac /((?:a?)*)*c/ aac 0: aac 1: /((?>a?)*)*c/ aac 0: aac 1: /-- End of testinput1 --/ pcre-8.31/testdata/testoutput20000644000222100022210000072347311762200666013407 00000000000000/-- This set of tests is not Perl-compatible. It checks on special features of PCRE's API, error diagnostics, and the compiled code of some patterns. It also checks the non-Perl syntax the PCRE supports (Python, .NET, Oniguruma). Finally, there are some tests where PCRE and Perl differ, either because PCRE can't be compatible, or there is a possible Perl bug. NOTE: This is a non-UTF set of tests. When UTF support is needed, use test 5, and if Unicode Property Support is needed, use test 7. --/ /(a)b|/I Capturing subpattern count = 1 No options No first char No need char /abc/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' abc 0: abc defabc 0: abc \Aabc 0: abc *** Failers No match \Adefabc No match ABC No match /^abc/I Capturing subpattern count = 0 Options: anchored No first char No need char abc 0: abc \Aabc 0: abc *** Failers No match defabc No match \Adefabc No match /a+bc/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /a*bc/I Capturing subpattern count = 0 No options No first char Need char = 'c' /a{3}bc/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /(abc|a+z)/I Capturing subpattern count = 1 No options First char = 'a' No need char /^abc$/I Capturing subpattern count = 0 Options: anchored No first char No need char abc 0: abc *** Failers No match def\nabc No match /ab\idef/X Failed: unrecognized character follows \ at offset 3 /(?X)ab\idef/X Failed: unrecognized character follows \ at offset 7 /x{5,4}/ Failed: numbers out of order in {} quantifier at offset 5 /z{65536}/ Failed: number too big in {} quantifier at offset 7 /[abcd/ Failed: missing terminating ] for character class at offset 5 /(?X)[\B]/ Failed: invalid escape sequence in character class at offset 6 /(?X)[\R]/ Failed: invalid escape sequence in character class at offset 6 /(?X)[\X]/ Failed: invalid escape sequence in character class at offset 6 /[\B]/BZ ------------------------------------------------------------------ Bra B Ket End ------------------------------------------------------------------ /[\R]/BZ ------------------------------------------------------------------ Bra R Ket End ------------------------------------------------------------------ /[\X]/BZ ------------------------------------------------------------------ Bra X Ket End ------------------------------------------------------------------ /[z-a]/ Failed: range out of order in character class at offset 3 /^*/ Failed: nothing to repeat at offset 1 /(abc/ Failed: missing ) at offset 4 /(?# abc/ Failed: missing ) after comment at offset 7 /(?z)abc/ Failed: unrecognized character after (? or (?- at offset 2 /.*b/I Capturing subpattern count = 0 No options First char at start or follows newline Need char = 'b' /.*?b/I Capturing subpattern count = 0 No options First char at start or follows newline Need char = 'b' /cat|dog|elephant/I Capturing subpattern count = 0 No options No first char No need char this sentence eventually mentions a cat 0: cat this sentences rambles on and on for a while and then reaches elephant 0: elephant /cat|dog|elephant/IS Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 3 Starting byte set: c d e this sentence eventually mentions a cat 0: cat this sentences rambles on and on for a while and then reaches elephant 0: elephant /cat|dog|elephant/IiS Capturing subpattern count = 0 Options: caseless No first char No need char Subject length lower bound = 3 Starting byte set: C D E c d e this sentence eventually mentions a CAT cat 0: CAT this sentences rambles on and on for a while to elephant ElePhant 0: elephant /a|[bcd]/IS Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b c d /(a|[^\dZ])/IS Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff /(a|b)*[\s]/IS Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: \x09 \x0a \x0c \x0d \x20 a b /(ab\2)/ Failed: reference to non-existent subpattern at offset 6 /{4,5}abc/ Failed: nothing to repeat at offset 4 /(a)(b)(c)\2/I Capturing subpattern count = 3 Max back reference = 2 No options First char = 'a' Need char = 'c' abcb 0: abcb 1: a 2: b 3: c \O0abcb Matched, but too many substrings \O3abcb Matched, but too many substrings 0: abcb \O6abcb Matched, but too many substrings 0: abcb 1: a \O9abcb Matched, but too many substrings 0: abcb 1: a 2: b \O12abcb 0: abcb 1: a 2: b 3: c /(a)bc|(a)(b)\2/I Capturing subpattern count = 3 Max back reference = 2 No options First char = 'a' No need char abc 0: abc 1: a \O0abc Matched, but too many substrings \O3abc Matched, but too many substrings 0: abc \O6abc 0: abc 1: a aba 0: aba 1: 2: a 3: b \O0aba Matched, but too many substrings \O3aba Matched, but too many substrings 0: aba \O6aba Matched, but too many substrings 0: aba 1: \O9aba Matched, but too many substrings 0: aba 1: 2: a \O12aba 0: aba 1: 2: a 3: b /abc$/IE Capturing subpattern count = 0 Options: dollar_endonly First char = 'a' Need char = 'c' abc 0: abc *** Failers No match abc\n No match abc\ndef No match /(a)(b)(c)(d)(e)\6/ Failed: reference to non-existent subpattern at offset 17 /the quick brown fox/I Capturing subpattern count = 0 No options First char = 't' Need char = 'x' the quick brown fox 0: the quick brown fox this is a line with the quick brown fox 0: the quick brown fox /the quick brown fox/IA Capturing subpattern count = 0 Options: anchored No first char No need char the quick brown fox 0: the quick brown fox *** Failers No match this is a line with the quick brown fox No match /ab(?z)cd/ Failed: unrecognized character after (? or (?- at offset 4 /^abc|def/I Capturing subpattern count = 0 No options No first char No need char abcdef 0: abc abcdef\B 0: def /.*((abc)$|(def))/I Capturing subpattern count = 3 No options First char at start or follows newline No need char defabc 0: defabc 1: abc 2: abc \Zdefabc 0: def 1: def 2: 3: def /)/ Failed: unmatched parentheses at offset 0 /a[]b/ Failed: missing terminating ] for character class at offset 4 /[^aeiou ]{3,}/I Capturing subpattern count = 0 No options No first char No need char co-processors, and for 0: -pr /<.*>/I Capturing subpattern count = 0 No options First char = '<' Need char = '>' abcghinop 0: ghi /<.*?>/I Capturing subpattern count = 0 No options First char = '<' Need char = '>' abcghinop 0: /<.*>/IU Capturing subpattern count = 0 Options: ungreedy First char = '<' Need char = '>' abcghinop 0: /(?U)<.*>/I Capturing subpattern count = 0 Options: ungreedy First char = '<' Need char = '>' abcghinop 0: /<.*?>/IU Capturing subpattern count = 0 Options: ungreedy First char = '<' Need char = '>' abcghinop 0: ghi /={3,}/IU Capturing subpattern count = 0 Options: ungreedy First char = '=' Need char = '=' abc========def 0: === /(?U)={3,}?/I Capturing subpattern count = 0 Options: ungreedy First char = '=' Need char = '=' abc========def 0: ======== /(?^abc)/Im Capturing subpattern count = 0 Options: multiline First char at start or follows newline Need char = 'c' abc 0: abc def\nabc 0: abc *** Failers No match defabc No match /(?<=ab(c+)d)ef/ Failed: lookbehind assertion is not fixed length at offset 11 /(?<=ab(?<=c+)d)ef/ Failed: lookbehind assertion is not fixed length at offset 12 /(?<=ab(c|de)f)g/ Failed: lookbehind assertion is not fixed length at offset 13 /The next three are in testinput2 because they have variable length branches/ /(?<=bullock|donkey)-cart/I Capturing subpattern count = 0 No options First char = '-' Need char = 't' Max lookbehind = 7 the bullock-cart 0: -cart a donkey-cart race 0: -cart *** Failers No match cart No match horse-and-cart No match /(?<=ab(?i)x|y|z)/I Capturing subpattern count = 0 No options No first char No need char Max lookbehind = 3 /(?>.*)(?<=(abcd)|(xyz))/I Capturing subpattern count = 2 No options First char at start or follows newline No need char Max lookbehind = 4 alphabetabcd 0: alphabetabcd 1: abcd endingxyz 0: endingxyz 1: 2: xyz /(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/I Capturing subpattern count = 0 No options First char = 'Z' Need char = 'Z' Max lookbehind = 4 abxyZZ 0: ZZ abXyZZ 0: ZZ ZZZ 0: ZZ zZZ 0: ZZ bZZ 0: ZZ BZZ 0: ZZ *** Failers No match ZZ No match abXYZZ No match zzz No match bzz No match /(? 3: f 1G a (1) 2G (0) 3G f (1) get substring 4 failed -7 0L adef 1L a 2L 3L f bcdef\G1\G2\G3\G4\L 0: bcdef 1: bc 2: bc 3: f 1G bc (2) 2G bc (2) 3G f (1) get substring 4 failed -7 0L bcdef 1L bc 2L bc 3L f adefghijk\C0 0: adef 1: a 2: 3: f 0C adef (4) /^abc\00def/I Capturing subpattern count = 0 Options: anchored No first char No need char abc\00def\L\C0 0: abc\x00def 0C abc\x00def (7) 0L abc /word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )?)?)?)?)?)?)?)?)?otherword/I Capturing subpattern count = 8 Contains explicit CR or LF match No options First char = 'w' Need char = 'd' /.*X/IDZ ------------------------------------------------------------------ Bra Any* X Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char at start or follows newline Need char = 'X' /.*X/IDZs ------------------------------------------------------------------ Bra AllAny* X Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored dotall No first char Need char = 'X' /(.*X|^B)/IDZ ------------------------------------------------------------------ Bra CBra 1 Any* X Alt ^ B Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 No options First char at start or follows newline No need char /(.*X|^B)/IDZs ------------------------------------------------------------------ Bra CBra 1 AllAny* X Alt ^ B Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: anchored dotall No first char No need char /(?s)(.*X|^B)/IDZ ------------------------------------------------------------------ Bra CBra 1 AllAny* X Alt ^ B Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: anchored dotall No first char No need char /(?s:.*X|^B)/IDZ ------------------------------------------------------------------ Bra Bra AllAny* X Alt ^ B Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /\Biss\B/I+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Max lookbehind = 1 Mississippi 0: iss 0+ issippi /iss/IG+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Mississippi 0: iss 0+ issippi 0: iss 0+ ippi /\Biss\B/IG+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Max lookbehind = 1 Mississippi 0: iss 0+ issippi /\Biss\B/Ig+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Max lookbehind = 1 Mississippi 0: iss 0+ issippi 0: iss 0+ ippi *** Failers No match Mississippi\A No match /(?<=[Ms])iss/Ig+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Max lookbehind = 1 Mississippi 0: iss 0+ issippi 0: iss 0+ ippi /(?<=[Ms])iss/IG+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Max lookbehind = 1 Mississippi 0: iss 0+ issippi /^iss/Ig+ Capturing subpattern count = 0 Options: anchored No first char No need char ississippi 0: iss 0+ issippi /.*iss/Ig+ Capturing subpattern count = 0 No options First char at start or follows newline Need char = 's' abciss\nxyzisspqr 0: abciss 0+ \x0axyzisspqr 0: xyziss 0+ pqr /.i./I+g Capturing subpattern count = 0 No options No first char Need char = 'i' Mississippi 0: Mis 0+ sissippi 0: sis 0+ sippi 0: sip 0+ pi Mississippi\A 0: Mis 0+ sissippi 0: sis 0+ sippi 0: sip 0+ pi Missouri river 0: Mis 0+ souri river 0: ri 0+ river 0: riv 0+ er Missouri river\A 0: Mis 0+ souri river /^.is/I+g Capturing subpattern count = 0 Options: anchored No first char No need char Mississippi 0: Mis 0+ sissippi /^ab\n/Ig+ Capturing subpattern count = 0 Contains explicit CR or LF match Options: anchored No first char No need char ab\nab\ncd 0: ab\x0a 0+ ab\x0acd /^ab\n/Img+ Capturing subpattern count = 0 Contains explicit CR or LF match Options: multiline First char at start or follows newline Need char = \x0a ab\nab\ncd 0: ab\x0a 0+ ab\x0acd 0: ab\x0a 0+ cd /abc/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /abc|bac/I Capturing subpattern count = 0 No options No first char Need char = 'c' /(abc|bac)/I Capturing subpattern count = 1 No options No first char Need char = 'c' /(abc|(c|dc))/I Capturing subpattern count = 2 No options No first char Need char = 'c' /(abc|(d|de)c)/I Capturing subpattern count = 2 No options No first char Need char = 'c' /a*/I Capturing subpattern count = 0 No options No first char No need char /a+/I Capturing subpattern count = 0 No options First char = 'a' No need char /(baa|a+)/I Capturing subpattern count = 1 No options No first char Need char = 'a' /a{0,3}/I Capturing subpattern count = 0 No options No first char No need char /baa{3,}/I Capturing subpattern count = 0 No options First char = 'b' Need char = 'a' /"([^\\"]+|\\.)*"/I Capturing subpattern count = 1 No options First char = '"' Need char = '"' /(abc|ab[cd])/I Capturing subpattern count = 1 No options First char = 'a' No need char /(a|.)/I Capturing subpattern count = 1 No options No first char No need char /a|ba|\w/I Capturing subpattern count = 0 No options No first char No need char /abc(?=pqr)/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'r' /...(?<=abc)/I Capturing subpattern count = 0 No options No first char No need char Max lookbehind = 3 /abc(?!pqr)/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /ab./I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /ab[xyz]/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /abc*/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /ab.c*/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /a.c*/I Capturing subpattern count = 0 No options First char = 'a' No need char /.c*/I Capturing subpattern count = 0 No options No first char No need char /ac*/I Capturing subpattern count = 0 No options First char = 'a' No need char /(a.c*|b.c*)/I Capturing subpattern count = 1 No options No first char No need char /a.c*|aba/I Capturing subpattern count = 0 No options First char = 'a' No need char /.+a/I Capturing subpattern count = 0 No options No first char Need char = 'a' /(?=abcda)a.*/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'a' /(?=a)a.*/I Capturing subpattern count = 0 No options First char = 'a' No need char /a(b)*/I Capturing subpattern count = 1 No options First char = 'a' No need char /a\d*/I Capturing subpattern count = 0 No options First char = 'a' No need char /ab\d*/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /a(\d)*/I Capturing subpattern count = 1 No options First char = 'a' No need char /abcde{0,0}/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'd' /ab\d+/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /a(?(1)b)(.)/I Capturing subpattern count = 1 No options First char = 'a' No need char /a(?(1)bag|big)(.)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'g' /a(?(1)bag|big)*(.)/I Capturing subpattern count = 1 No options First char = 'a' No need char /a(?(1)bag|big)+(.)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'g' /a(?(1)b..|b..)(.)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' /ab\d{0}e/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'e' /a?b?/I Capturing subpattern count = 0 No options No first char No need char a 0: a b 0: b ab 0: ab \ 0: *** Failers 0: \N No match /|-/I Capturing subpattern count = 0 No options No first char No need char abcd 0: -abc 0: \Nab-c 0: - *** Failers 0: \Nabc No match /^.?abcd/IS Capturing subpattern count = 0 Options: anchored No first char Need char = 'd' Subject length lower bound = 4 No set of starting bytes /\( # ( at start (?: # Non-capturing bracket (?>[^()]+) # Either a sequence of non-brackets (no backtracking) | # Or (?R) # Recurse - i.e. nested bracketed string )* # Zero or more contents \) # Closing ) /Ix Capturing subpattern count = 0 Options: extended First char = '(' Need char = ')' (abcd) 0: (abcd) (abcd)xyz 0: (abcd) xyz(abcd) 0: (abcd) (ab(xy)cd)pqr 0: (ab(xy)cd) (ab(xycd)pqr 0: (xycd) () abc () 0: () 12(abcde(fsh)xyz(foo(bar))lmno)89 0: (abcde(fsh)xyz(foo(bar))lmno) *** Failers No match abcd No match abcd) No match (abcd No match /\( ( (?>[^()]+) | (?R) )* \) /Ixg Capturing subpattern count = 1 Options: extended First char = '(' Need char = ')' (ab(xy)cd)pqr 0: (ab(xy)cd) 1: cd 1(abcd)(x(y)z)pqr 0: (abcd) 1: abcd 0: (x(y)z) 1: z /\( (?: (?>[^()]+) | (?R) ) \) /Ix Capturing subpattern count = 0 Options: extended First char = '(' Need char = ')' (abcd) 0: (abcd) (ab(xy)cd) 0: (xy) (a(b(c)d)e) 0: (c) ((ab)) 0: ((ab)) *** Failers No match () No match /\( (?: (?>[^()]+) | (?R) )? \) /Ix Capturing subpattern count = 0 Options: extended First char = '(' Need char = ')' () 0: () 12(abcde(fsh)xyz(foo(bar))lmno)89 0: (fsh) /\( ( (?>[^()]+) | (?R) )* \) /Ix Capturing subpattern count = 1 Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: cd /\( ( ( (?>[^()]+) | (?R) )* ) \) /Ix Capturing subpattern count = 2 Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: ab(xy)cd 2: cd /\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /Ix Capturing subpattern count = 3 Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: 2: ab(xy)cd 3: cd (123ab(xy)cd) 0: (123ab(xy)cd) 1: 123 2: ab(xy)cd 3: cd /\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /Ix Capturing subpattern count = 3 Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: ab(xy)cd 2: 3: cd (123ab(xy)cd) 0: (123ab(xy)cd) 1: 123ab(xy)cd 2: 123 3: cd /\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /Ix Capturing subpattern count = 11 Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: ab(xy)cd 2: ab(xy)cd 3: ab(xy)cd 4: ab(xy)cd 5: ab(xy)cd 6: ab(xy)cd 7: ab(xy)cd 8: ab(xy)cd 9: ab(xy)cd 10: ab(xy)cd 11: cd /\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /Ix Capturing subpattern count = 3 Options: extended First char = '(' Need char = ')' (abcd(xyz

qrs)123) 0: (abcd(xyz

qrs)123) 1: abcd(xyz

qrs)123) /\( ( ( (?>[^()]+) | ((?R)) )* ) \) /Ix (ab(cd)ef) (ab(cd(ef)gh)ij) /^[[:alnum:]]/DZ /^[[:^alnum:]]/DZ /^[[:alpha:]]/DZ /^[[:^alpha:]]/DZ /[_[:alpha:]]/IS /^[[:ascii:]]/DZ /^[[:^ascii:]]/DZ /^[[:blank:]]/DZ /^[[:^blank:]]/DZ /[\n\x0b\x0c\x0d[:blank:]]/IS /^[[:cntrl:]]/DZ /^[[:digit:]]/DZ /^[[:graph:]]/DZ /^[[:lower:]]/DZ /^[[:print:]]/DZ /^[[:punct:]]/DZ /^[[:space:]]/DZ /^[[:upper:]]/DZ /^[[:xdigit:]]/DZ /^[[:word:]]/DZ /^[[:^cntrl:]]/DZ /^[12[:^digit:]]/DZ /^[[:^blank:]]/DZ /[01[:alpha:]%]/DZ /[[.ch.]]/I /[[=ch=]]/I /[[:rhubarb:]]/I /[[:upper:]]/Ii A a /[[:lower:]]/Ii A a /((?-i)[[:lower:]])[[:lower:]]/Ii ab aB *** Failers Ab AB /[\200-\110]/I /^(?(0)f|b)oo/I /This one's here because of the large output vector needed/I /(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/I \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC /This one's here because Perl does this differently and PCRE can't at present/I /(main(O)?)+/I mainmain mainOmain /These are all cases where Perl does it differently (nested captures)/I /^(a(b)?)+$/I aba /^(aa(bb)?)+$/I aabbaa /^(aa|aa(bb))+$/I aabbaa /^(aa(bb)??)+$/I aabbaa /^(?:aa(bb)?)+$/I aabbaa /^(aa(b(b))?)+$/I aabbaa /^(?:aa(b(b))?)+$/I aabbaa /^(?:aa(b(?:b))?)+$/I aabbaa /^(?:aa(bb(?:b))?)+$/I aabbbaa /^(?:aa(b(?:bb))?)+$/I aabbbaa /^(?:aa(?:b(b))?)+$/I aabbaa /^(?:aa(?:b(bb))?)+$/I aabbbaa /^(aa(b(bb))?)+$/I aabbbaa /^(aa(bb(bb))?)+$/I aabbbbaa /--------------------------------------------------------------------/I /#/IxDZ /a#/IxDZ /[\s]/DZ /[\S]/DZ /a(?i)b/DZ ab aB *** Failers AB /(a(?i)b)/DZ ab aB *** Failers AB / (?i)abc/IxDZ /#this is a comment (?i)abc/IxDZ /123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ /\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ /\Q\E/DZ \ /\Q\Ex/DZ / \Q\E/DZ /a\Q\E/DZ abc bca bac /a\Q\Eb/DZ abc /\Q\Eabc/DZ /x*+\w/DZ *** Failers xxxxx /x?+/DZ /x++/DZ /x{1,3}+/DZ /(x)*+/DZ /^(\w++|\s++)*$/I now is the time for all good men to come to the aid of the party *** Failers this is not a line with only words and spaces! /(\d++)(\w)/I 12345a *** Failers 12345+ /a++b/I aaab /(a++b)/I aaab /(a++)b/I aaab /([^()]++|\([^()]*\))+/I ((abc(ade)ufh()()x /\(([^()]++|\([^()]+\))+\)/I (abc) (abc(def)xyz) *** Failers ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /(abc){1,3}+/DZ /a+?+/I /a{2,3}?+b/I /(?U)a+?+/I /a{2,3}?+b/IU /x(?U)a++b/DZ xaaaab /(?U)xa++b/DZ xaaaab /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/DZ /^x(?U)a+b/DZ /^x(?U)(a+)b/DZ /[.x.]/I /[=x=]/I /[:x:]/I /\l/I /\L/I /\N{name}/I /\u/I /\U/I /[/I /[a-/I /[[:space:]/I /[\s]/IDZ /[[:space:]]/IDZ /[[:space:]abcde]/IDZ /< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/Ix <> hij> hij> def> *** Failers iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|IDZ |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|IDZ /(.*)\d+\1/I /(.*)\d+/I /(.*)\d+\1/Is /(.*)\d+/Is /(.*(xyz))\d+\2/I /((.*))\d+\1/I abc123bc /a[b]/I /(?=a).*/I /(?=abc).xyz/IiI /(?=abc)(?i).xyz/I /(?=a)(?=b)/I /(?=.)a/I /((?=abcda)a)/I /((?=abcda)ab)/I /()a/I /(?(1)ab|ac)(.)/I /(?(1)abz|acz)(.)/I /(?(1)abz)(.)/I /(?(1)abz)(1)23/I /(a)+/I /(a){2,3}/I /(a)*/I /[a]/I /[ab]/I /[ab]/IS /[^a]/I /\d456/I /\d456/IS /a^b/I /^a/Im abcde xy\nabc *** Failers xyabc /c|abc/I /(?i)[ab]/IS /[ab](?i)cd/IS /abc(?C)def/I abcdef 1234abcdef *** Failers abcxyz abcxyzf /abc(?C)de(?C1)f/I 123abcdef /(?C1)\dabc(?C2)def/IS 1234abcdef *** Failers abcdef /(?C1)\dabc(?C2)def/ISS 1234abcdef *** Failers abcdef /(?C255)ab/I /(?C256)ab/I /(?Cab)xx/I /(?C12vr)x/I /abc(?C)def/I *** Failers \x83\x0\x61bcdef /(abc)(?C)de(?C1)f/I 123abcdef 123abcdef\C+ 123abcdef\C- *** Failers 123abcdef\C!1 /(?C0)(abc(?C1))*/I abcabcabc abcabc\C!1!3 *** Failers abcabcabc\C!1!3 /(\d{3}(?C))*/I 123\C+ 123456\C+ 123456789\C+ /((xyz)(?C)p|(?C1)xyzabc)/I xyzabc\C+ /(X)((xyz)(?C)p|(?C1)xyzabc)/I Xxyzabc\C+ /(?=(abc))(?C)abcdef/I abcdef\C+ /(?!(abc)(?C1)d)(?C2)abcxyz/I abcxyz\C+ /(?<=(abc)(?C))xyz/I abcxyz\C+ /a(b+)(c*)(?C1)/I abbbbbccc\C*1 /a(b+?)(c*?)(?C1)/I abbbbbccc\C*1 /(?C)abc/I /(?C)^abc/I /(?C)a|b/IS /(?R)/I /(a|(?R))/I /(ab|(bc|(de|(?R))))/I /x(ab|(bc|(de|(?R))))/I xab xbc xde xxab xxxab *** Failers xyab /(ab|(bc|(de|(?1))))/I /x(ab|(bc|(de|(?1)x)x)x)/I /^([^()]|\((?1)*\))*$/I abc a(b)c a(b(c))d *** Failers) a(b(c)d /^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/Ix <> hij> hij> def> *** Failers b|c)d(?Pe)/DZ abde acde /(?:a(?Pc(?Pd)))(?Pa)/DZ /(?Pa)...(?P=a)bbb(?P>a)d/DZ /^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/Ii 1221 Satan, oscillate my metallic sonatas! A man, a plan, a canal: Panama! Able was I ere I saw Elba. *** Failers The quick brown fox /((?(R)a|b))\1(?1)?/I bb bbaa /(.*)a/Is /(.*)a\1/Is /(.*)a(b)\2/Is /((.*)a|(.*)b)z/Is /((.*)a|(.*)b)z\1/Is /((.*)a|(.*)b)z\2/Is /((.*)a|(.*)b)z\3/Is /((.*)a|^(.*)b)z\3/Is /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/Is /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/Is /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/Is /(a)(bc)/INDZ abc /(?Pa)(bc)/INDZ abc /(a)(?Pbc)/INDZ /(a+)*zz/I aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M aaaaaaaaaaaaaz\M /(aaa(?C1)bbb|ab)/I aaabbb aaabbb\C*0 aaabbb\C*1 aaabbb\C*-1 /ab(?Pcd)ef(?Pgh)/I abcdefgh abcdefgh\C1\Gtwo abcdefgh\Cone\Ctwo abcdefgh\Cthree /(?P)(?P)/DZ /(?P)(?P)/DZ /(?Pzz)(?Paa)/I zzaa\CZ zzaa\CA /(?Peks)(?Peccs)/I /(?Pabc(?Pdef)(?Pxyz))/I "\[((?P\d+)(,(?P>elem))*)\]"I [10,20,30,5,5,4,4,2,43,23,4234] *** Failers [] "\[((?P\d+)(,(?P>elem))*)?\]"I [10,20,30,5,5,4,4,2,43,23,4234] [] /(a(b(?2)c))?/DZ /(a(b(?2)c))*/DZ /(a(b(?2)c)){0,2}/DZ /[ab]{1}+/DZ /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/Ii Baby Bjorn Active Carrier - With free SHIPPING!! /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/IiS Baby Bjorn Active Carrier - With free SHIPPING!! /a*.*b/ISDZ /(a|b)*.?c/ISDZ /abc(?C255)de(?C)f/DZ /abcde/ICDZ abcde abcdfe /a*b/ICDZS ab aaaab aaaacb /a*b/ICDZSS ab aaaab aaaacb /a+b/ICDZ ab aaaab aaaacb /(abc|def)x/ICDZS abcx defx ** Failers abcdefzx /(abc|def)x/ICDZSS abcx defx ** Failers abcdefzx /(ab|cd){3,4}/IC ababab abcdabcd abcdcdcdcdcd /([ab]{,4}c|xy)/ICDZS Note: that { does NOT introduce a quantifier /([ab]{,4}c|xy)/ICDZSS Note: that { does NOT introduce a quantifier /([ab]{1,4}c|xy){4,5}?123/ICDZ aacaacaacaacaac123 /\b.*/I ab cd\>1 /\b.*/Is ab cd\>1 /(?!.bcd).*/I Xbcd12345 /abcde/I ab\P abc\P abcd\P abcde\P the quick brown abc\P ** Failers\P the quick brown abxyz fox\P "^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$"I 13/05/04\P 13/5/2004\P 02/05/09\P 1\P 1/2\P 1/2/0\P 1/2/04\P 0\P 02/\P 02/0\P 02/1\P ** Failers\P \P 123\P 33/4/04\P 3/13/04\P 0/1/2003\P 0/\P 02/0/\P 02/13\P /0{0,2}ABC/I /\d{3,}ABC/I /\d*ABC/I /[abc]+DE/I /[abc]?123/I 123\P a\P b\P c\P c12\P c123\P /^(?:\d){3,5}X/I 1\P 123\P 123X 1234\P 1234X 12345\P 12345X *** Failers 1X 123456\P /abc/IS>testsavedregex testsavedregex testsavedregex testsavedregex testsavedregex testsavedregex testsavedregex testsavedregex (.)*~smgI \J1024\n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n /^a/IF /line\nbreak/I this is a line\nbreak line one\nthis is a line\nbreak in the second line /line\nbreak/If this is a line\nbreak ** Failers line one\nthis is a line\nbreak in the second line /line\nbreak/Imf this is a line\nbreak ** Failers line one\nthis is a line\nbreak in the second line /(?i)(?-i)AbCd/I AbCd ** Failers abcd /a{11111111111111111111}/I /(){64294967295}/I /(){2,4294967295}/I "(?i:a)(?i:b)(?i:c)(?i:d)(?i:e)(?i:f)(?i:g)(?i:h)(?i:i)(?i:j)(k)(?i:l)A\1B"I abcdefghijklAkB "(?Pa)(?Pb)(?Pc)(?Pd)(?Pe)(?Pf)(?Pg)(?Ph)(?Pi)(?Pj)(?Pk)(?Pl)A\11B"I abcdefghijklAkB "(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)A\11B"I abcdefghijklAkB "(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)"I aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)"I aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /[^()]*(?:\((?R)\)[^()]*)*/I (this(and)that (this(and)that) (this(and)that)stuff /[^()]*(?:\((?>(?R))\)[^()]*)*/I (this(and)that (this(and)that) /[^()]*(?:\((?R)\))*[^()]*/I (this(and)that (this(and)that) /(?:\((?R)\))*[^()]*/I (this(and)that (this(and)that) ((this)) /(?:\((?R)\))|[^()]*/I (this(and)that (this(and)that) (this) ((this)) /\x{0000ff}/I /^((?Pa1)|(?Pa2)b)/I /^((?Pa1)|(?Pa2)b)/IJ a1b\CA a2b\CA ** Failers a1b\CZ\CA /^(?Pa)(?Pb)/IJ ab\CA /^(?Pa)(?Pb)|cd/IJ ab\CA cd\CA /^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ cdefgh\CA /^((?Pa1)|(?Pa2)b)/IJ a1b\GA a2b\GA ** Failers a1b\GZ\GA /^(?Pa)(?Pb)/IJ ab\GA /^(?Pa)(?Pb)|cd/IJ ab\GA cd\GA /^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ cdefgh\GA /(?J)^((?Pa1)|(?Pa2)b)/I a1b\CA a2b\CA /^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I / 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. /Ix /^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I a bc d\CA\CB\CC /^(?Pa)?(?(A)a|b)/I aabc bc ** Failers abc /(?:(?(ZZ)a|b)(?PX))+/I bXaX /(?:(?(2y)a|b)(X))+/I /(?:(?(ZA)a|b)(?PX))+/I /(?:(?(ZZ)a|b)(?(ZZ)a|b)(?PX))+/I bbXaaX /(?:(?(ZZ)a|\(b\))\\(?PX))+/I (b)\\Xa\\X /(?PX|Y))+/I bXXaYYaY bXYaXXaX /()()()()()()()()()(?:(?(A)(?P=A)a|b)(?PX|Y))+/I bXXaYYaY /\s*,\s*/IS \x0b,\x0b \x0c,\x0d /^abc/Im xyz\nabc xyz\nabc\ xyz\r\nabc\ xyz\rabc\ xyz\r\nabc\ ** Failers xyz\nabc\ xyz\r\nabc\ xyz\nabc\ xyz\rabc\ xyz\rabc\ /abc$/Im xyzabc xyzabc\n xyzabc\npqr xyzabc\r\ xyzabc\rpqr\ xyzabc\r\n\ xyzabc\r\npqr\ ** Failers xyzabc\r xyzabc\rpqr xyzabc\r\n xyzabc\r\npqr /^abc/Im xyz\rabcdef xyz\nabcdef\ ** Failers xyz\nabcdef /^abc/Im xyz\nabcdef xyz\rabcdef\ ** Failers xyz\rabcdef /^abc/Im xyz\r\nabcdef xyz\rabcdef\ ** Failers xyz\rabcdef /^abc/Im /abc/I xyz\rabc\ abc /.*/I abc\ndef abc\rdef abc\r\ndef \abc\ndef \abc\rdef \abc\r\ndef \abc\ndef \abc\rdef \abc\r\ndef /\w+(.)(.)?def/Is abc\ndef abc\rdef abc\r\ndef +((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+I /* this is a C style comment */\M /(?P25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?P>B)){3}/I /()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() (.(.))/Ix XY\O400 /(a*b|(?i:c*(?-i)d))/IS /()[ab]xyz/IS /(|)[ab]xyz/IS /(|c)[ab]xyz/IS /(|c?)[ab]xyz/IS /(d?|c?)[ab]xyz/IS /(d?|c)[ab]xyz/IS /^a*b\d/DZ /^a*+b\d/DZ /^a*?b\d/DZ /^a+A\d/DZ aaaA5 ** Failers aaaa5 /^a*A\d/IiDZ aaaA5 aaaa5 /(a*|b*)[cd]/IS /(a+|b*)[cd]/IS /(a*|b+)[cd]/IS /(a+|b+)[cd]/IS /(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( ((( a )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) ))) /Ix large nest /a*\d/BZ /a*\D/BZ /0*\d/BZ /0*\D/BZ /a*\s/BZ /a*\S/BZ / *\s/BZ / *\S/BZ /a*\w/BZ /a*\W/BZ /=*\w/BZ /=*\W/BZ /\d*a/BZ /\d*2/BZ /\d*\d/BZ /\d*\D/BZ /\d*\s/BZ /\d*\S/BZ /\d*\w/BZ /\d*\W/BZ /\D*a/BZ /\D*2/BZ /\D*\d/BZ /\D*\D/BZ /\D*\s/BZ /\D*\S/BZ /\D*\w/BZ /\D*\W/BZ /\s*a/BZ /\s*2/BZ /\s*\d/BZ /\s*\D/BZ /\s*\s/BZ /\s*\S/BZ /\s*\w/BZ /\s*\W/BZ /\S*a/BZ /\S*2/BZ /\S*\d/BZ /\S*\D/BZ /\S*\s/BZ /\S*\S/BZ /\S*\w/BZ /\S*\W/BZ /\w*a/BZ /\w*2/BZ /\w*\d/BZ /\w*\D/BZ /\w*\s/BZ /\w*\S/BZ /\w*\w/BZ /\w*\W/BZ /\W*a/BZ /\W*2/BZ /\W*\d/BZ /\W*\D/BZ /\W*\s/BZ /\W*\S/BZ /\W*\w/BZ /\W*\W/BZ /[^a]+a/BZ /[^a]+a/BZi /[^a]+A/BZi /[^a]+b/BZ /[^a]+\d/BZ /a*[^a]/BZ /(?Px)(?Py)/I xy\Cabc\Cxyz /(?x)(?'xyz'y)/I xy\Cabc\Cxyz /(?x)(?'xyz>y)/I /(?P'abc'x)(?Py)/I /^(?:(?(ZZ)a|b)(?X))+/ bXaX bXbX ** Failers aXaX aXbX /^(?P>abc)(?xxx)/ /^(?P>abc)(?x|y)/ xx xy yy yx /^(?P>abc)(?Px|y)/ xx xy yy yx /^((?(abc)a|b)(?x|y))+/ bxay bxby ** Failers axby /^(((?P=abc)|X)(?x|y))+/ XxXxxx XxXyyx XxXyxx ** Failers x /^(?1)(abc)/ abcabc /^(?:(?:\1|X)(a|b))+/ Xaaa Xaba /^[\E\Qa\E-\Qz\E]+/BZ /^[a\Q]bc\E]/BZ /^[a-\Q\E]/BZ /^(?P>abc)[()](?)/BZ /^((?(abc)y)[()](?Px))+/BZ (xy)x /^(?P>abc)\Q()\E(?)/BZ /^(?P>abc)[a\Q(]\E(](?)/BZ /^(?P>abc) # this is (a comment) (?)/BZx /^\W*(?:(?(?.)\W*(?&one)\W*\k|)|(?(?.)\W*(?&three)\W*\k'four'|\W*.\W*))\W*$/Ii 1221 Satan, oscillate my metallic sonatas! A man, a plan, a canal: Panama! Able was I ere I saw Elba. *** Failers The quick brown fox /(?=(\w+))\1:/I abcd: /(?=(?'abc'\w+))\k:/I abcd: /(?'abc'a|b)(?d|e)\k{2}/J adaa ** Failers addd adbb /(?'abc'a|b)(?d|e)(?&abc){2}/J bdaa bdab ** Failers bddd /(?( (?'B' abc (?(R) (?(R&A)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x abcabc1Xabc2XabcXabcabc /(? (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x /(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x abcabc1Xabc2XabcXabcabc /^(?(DEFINE) abc | xyz ) /x /(?(DEFINE) abc) xyz/xI /(a|)*\d/ \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /^a.b/ a\rb a\nb\ a\x85b\ ** Failers a\nb a\nb\ a\rb\ a\rb\ a\x85b\ a\rb\ /^abc./mgx abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK /abc.$/mgx abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc7 abc9 /a/ /a/ /^a\Rb/ a\nb a\rb a\r\nb a\x0bb a\x0cb a\x85b ** Failers a\n\rb /^a\R*b/ ab a\nb a\rb a\r\nb a\x0bb a\x0cb a\x85b a\n\rb a\n\r\x85\x0cb /^a\R+b/ a\nb a\rb a\r\nb a\x0bb a\x0cb a\x85b a\n\rb a\n\r\x85\x0cb ** Failers ab /^a\R{1,3}b/ a\nb a\n\rb a\n\r\x85b a\r\n\r\nb a\r\n\r\n\r\nb a\n\r\n\rb a\n\n\r\nb ** Failers a\n\n\n\rb a\r /^a[\R]b/ aRb ** Failers a\nb /(?&abc)X(?P)/I abcPXP123 /(?1)X(?P)/I abcPXP123 /(?:a(?&abc)b)*(?x)/ 123axbaxbaxbx456 123axbaxbaxb456 /(?:a(?&abc)b){1,5}(?x)/ 123axbaxbaxbx456 /(?:a(?&abc)b){2,5}(?x)/ 123axbaxbaxbx456 /(?:a(?&abc)b){2,}(?x)/ 123axbaxbaxbx456 /(abc)(?i:(?1))/ defabcabcxyz DEFabcABCXYZ /(abc)(?:(?i)(?1))/ defabcabcxyz DEFabcABCXYZ /^(a)\g-2/ /^(a)\g/ /^(a)\g{0}/ /^(a)\g{3/ /^(a)\g{4a}/ /^a.b/ a\rb *** Failers a\nb /.+foo/ afoo ** Failers \r\nfoo \nfoo /.+foo/ afoo \nfoo ** Failers \r\nfoo /.+foo/ afoo ** Failers \nfoo \r\nfoo /.+foo/s afoo \r\nfoo \nfoo /^$/mg abc\r\rxyz abc\n\rxyz ** Failers abc\r\nxyz /(?m)^$/g+ abc\r\n\r\n /(?m)^$|^\r\n/g+ abc\r\n\r\n /(?m)$/g+ abc\r\n\r\n /abc.$/mgx abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 /^X/m XABC ** Failers XABC\B /(ab|c)(?-1)/BZ abc /xy(?+1)(abc)/BZ xyabcabc ** Failers xyabc /x(?-0)y/ /x(?-1)y/ /x(?+0)y/ /x(?+1)y/ /^(abc)?(?(-1)X|Y)/BZ abcX Y ** Failers abcY /^((?(+1)X|Y)(abc))+/BZ YabcXabc YabcXabcXabc ** Failers XabcXabc /(?(-1)a)/BZ /((?(-1)a))/BZ /((?(-2)a))/BZ /^(?(+1)X|Y)(.)/BZ Y! /(?tom|bon)-\k{A}/ tom-tom bon-bon ** Failers tom-bon /\g{A/ /(?|(abc)|(xyz))/BZ >abc< >xyz< /(x)(?|(abc)|(xyz))(x)/BZ xabcx xxyzx /(x)(?|(abc)(pqr)|(xyz))(x)/BZ xabcpqrx xxyzx /\H++X/BZ ** Failers XXXX /\H+\hY/BZ XXXX Y /\H+ Y/BZ /\h+A/BZ /\v*B/BZ /\V+\x0a/BZ /A+\h/BZ / *\H/BZ /A*\v/BZ /\x0b*\V/BZ /\d+\h/BZ /\d*\v/BZ /S+\h\S+\v/BZ /\w{3,}\h\w+\v/BZ /\h+\d\h+\w\h+\S\h+\H/BZ /\v+\d\v+\w\v+\S\v+\V/BZ /\H+\h\H+\d/BZ /\V+\v\V+\w/BZ /\( (?: [^()]* | (?R) )* \)/x \J1024(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) /[\E]AAA/ /[\Q\E]AAA/ /[^\E]AAA/ /[^\Q\E]AAA/ /[\E^]AAA/ /[\Q\E^]AAA/ /A(*PRUNE)B(*SKIP)C(*THEN)D(*COMMIT)E(*F)F(*FAIL)G(?!)H(*ACCEPT)I/BZ /^a+(*FAIL)/C aaaaaa /a+b?c+(*FAIL)/C aaabccc /a+b?(*PRUNE)c+(*FAIL)/C aaabccc /a+b?(*COMMIT)c+(*FAIL)/C aaabccc /a+b?(*SKIP)c+(*FAIL)/C aaabcccaaabccc /a+b?(*THEN)c+(*FAIL)/C aaabccc /a(*MARK)b/ /(?i:A{1,}\6666666666)/ /\g6666666666/ /[\g6666666666]/BZ /(?1)\c[/ /.+A/ \r\nA /\nA/ \r\nA /[\r\n]A/ \r\nA /(\r|\n)A/ \r\nA /a(*CR)b/ /(*CR)a.b/ a\nb ** Failers a\rb /(*CR)a.b/ a\nb ** Failers a\rb /(*LF)a.b/ a\rb ** Failers a\nb /(*CRLF)a.b/ a\rb a\nb ** Failers a\r\nb /(*ANYCRLF)a.b/ ** Failers a\rb a\nb a\r\nb /(*ANY)a.b/ ** Failers a\rb a\nb a\r\nb a\x85b /(*ANY).*/g abc\r\ndef /(*ANYCRLF).*/g abc\r\ndef /(*CRLF).*/g abc\r\ndef /a\Rb/I a\rb a\nb a\r\nb ** Failers a\x85b a\x0bb /a\Rb/I a\rb a\nb a\r\nb a\x85b a\x0bb ** Failers a\x85b\ a\x0bb\ /a\R?b/I a\rb a\nb a\r\nb ** Failers a\x85b a\x0bb /a\R?b/I a\rb a\nb a\r\nb a\x85b a\x0bb ** Failers a\x85b\ a\x0bb\ /a\R{2,4}b/I a\r\n\nb a\n\r\rb a\r\n\r\n\r\n\r\nb ** Failers a\x85\85b a\x0b\0bb /a\R{2,4}b/I a\r\rb a\n\n\nb a\r\n\n\r\rb a\x85\85b a\x0b\0bb ** Failers a\r\r\r\r\rb a\x85\85b\ a\x0b\0bb\ /(*BSR_ANYCRLF)a\Rb/I a\nb a\rb /(*BSR_UNICODE)a\Rb/I a\x85b /(*BSR_ANYCRLF)(*CRLF)a\Rb/I a\nb a\rb /(*CRLF)(*BSR_UNICODE)a\Rb/I a\x85b /(*CRLF)(*BSR_ANYCRLF)(*CR)ab/I /(?)(?&)/ /(?)(?&a)/ /(?)(?&aaaaaaaaaaaaaaaaaaaaaaa)/ /(?+-a)/ /(?-+a)/ /(?(-1))/ /(?(+10))/ /(?(10))/ /(?(+2))()()/ /(?(2))()()/ /\k''/ /\k<>/ /\k{}/ /\k/ /\kabc/ /(?P=)/ /(?P>)/ /(?!\w)(?R)/ /(?=\w)(?R)/ /(?x|y){0}z/ xzxx yzyy ** Failers xxz /(\3)(\1)(a)/ cat /(\3)(\1)(a)/ cat /TA]/ The ACTA] comes /TA]/ The ACTA] comes /(?2)[]a()b](abc)/ abcbabc /(?2)[^]a()b](abc)/ abcbabc /(?1)[]a()b](abc)/ abcbabc ** Failers abcXabc /(?1)[^]a()b](abc)/ abcXabc ** Failers abcbabc /(?2)[]a()b](abc)(xyz)/ xyzbabcxyz /(?&N)[]a(?)](?abc)/ abc)](abc)/ abc ** Failers ab /a[]+b/ ** Failers ab /a[]*+b/ ** Failers ab /a[^]b/ aXb a\nb ** Failers ab /a[^]+b/ aXb a\nX\nXb ** Failers ab /a(?!)+b/ /a(*FAIL)+b/ /(abc|pqr|123){0}[xyz]/SI /(?(?=.*b)b|^)/CI adc abc /(?(?=b).*b|^d)/I /(?(?=.*b).*b|^d)/I /xyz/C xyz abcxyz abcxyz\Y ** Failers abc abc\Y abcxypqr abcxypqr\Y /(*NO_START_OPT)xyz/C abcxyz /xyz/CY abcxyz /^"((?(?=[a])[^"])|b)*"$/C "ab" /^"((?(?=[a])[^"])|b)*"$/ "ab" /^X(?5)(a)(?|(b)|(q))(c)(d)Y/ XYabcdY /^X(?&N)(a)(?|(b)|(q))(c)(d)(?Y)/ XYabcdY /Xa{2,4}b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /Xa{2,4}?b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /Xa{2,4}+b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X\d{2,4}b/ X\P X3\P X33\P X333\P X3333\P /X\d{2,4}?b/ X\P X3\P X33\P X333\P X3333\P /X\d{2,4}+b/ X\P X3\P X33\P X333\P X3333\P /X\D{2,4}b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X\D{2,4}?b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X\D{2,4}+b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X[abc]{2,4}b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X[abc]{2,4}?b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X[abc]{2,4}+b/ X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X[^a]{2,4}b/ X\P Xz\P Xzz\P Xzzz\P Xzzzz\P /X[^a]{2,4}?b/ X\P Xz\P Xzz\P Xzzz\P Xzzzz\P /X[^a]{2,4}+b/ X\P Xz\P Xzz\P Xzzz\P Xzzzz\P /(Y)X\1{2,4}b/ YX\P YXY\P YXYY\P YXYYY\P YXYYYY\P /(Y)X\1{2,4}?b/ YX\P YXY\P YXYY\P YXYYY\P YXYYYY\P /(Y)X\1{2,4}+b/ YX\P YXY\P YXYY\P YXYYY\P YXYYYY\P /\++\KZ|\d+X|9+Y/ ++++123999\P ++++123999Y\P ++++Z1234\P /Z(*F)/ Z\P ZA\P /Z(?!)/ Z\P ZA\P /dog(sbody)?/ dogs\P dogs\P\P /dog(sbody)??/ dogs\P dogs\P\P /dog|dogsbody/ dogs\P dogs\P\P /dogsbody|dog/ dogs\P dogs\P\P /\bthe cat\b/ the cat\P the cat\P\P /abc/ abc\P abc\P\P /abc\K123/ xyzabc123pqr xyzabc12\P xyzabc12\P\P /(?<=abc)123/ xyzabc123pqr xyzabc12\P xyzabc12\P\P /\babc\b/ +++abc+++ +++ab\P +++ab\P\P /(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/BZ /(?&word)(?&element)(?(DEFINE)(?<[^\d][^>]>[^<])(?\w*+))/BZ /(ab)(x(y)z(cd(*ACCEPT)))pq/BZ /abc\K/+ abcdef abcdef\N\N xyzabcdef\N\N ** Failers abcdef\N xyzabcdef\N /^(?:(?=abc)|abc\K)/+ abcdef abcdef\N\N ** Failers abcdef\N /a?b?/+ xyz xyzabc xyzabc\N xyzabc\N\N xyz\N\N ** Failers xyz\N /^a?b?/+ xyz xyzabc ** Failers xyzabc\N xyzabc\N\N xyz\N\N xyz\N /^(?a|b\gc)/ aaaa bacxxx bbaccxxx bbbacccxx /^(?a|b\g'name'c)/ aaaa bacxxx bbaccxxx bbbacccxx /^(a|b\g<1>c)/ aaaa bacxxx bbaccxxx bbbacccxx /^(a|b\g'1'c)/ aaaa bacxxx bbaccxxx bbbacccxx /^(a|b\g'-1'c)/ aaaa bacxxx bbaccxxx bbbacccxx /(^(a|b\g<-1>c))/ aaaa bacxxx bbaccxxx bbbacccxx /(?-i:\g)(?i:(?a))/ XaaX XAAX /(?i:\g)(?-i:(?a))/ XaaX ** Failers XAAX /(?-i:\g<+1>)(?i:(a))/ XaaX XAAX /(?=(?(?#simplesyntax)\$(?[a-zA-Z_\x{7f}-\x{ff}][a-zA-Z0-9_\x{7f}-\x{ff}]*)(?:\[(?[a-zA-Z0-9_\x{7f}-\x{ff}]+|\$\g)\]|->\g(\(.*?\))?)?|(?#simple syntax withbraces)\$\{(?:\g(?\[(?:\g|'(?:\\.|[^'\\])*'|"(?:\g|\\.|[^"\\])*")\])?|\g|\$\{\g\})\}|(?#complexsyntax)\{(?\$(?\g(\g*|\(.*?\))?)(?:->\g)*|\$\g|\$\{\g\})\}))\{/ /(?a|b|c)\g*/ abc accccbbb /^X(?7)(a)(?|(b)|(q)(r)(s))(c)(d)(Y)/ XYabcdY /(?<=b(?1)|zzz)(a)/ xbaax xzzzax /(a)(?<=b\1)/ /(a)(?<=b+(?1))/ /(a+)(?<=b(?1))/ /(a(?<=b(?1)))/ /(?<=b(?1))xyz/ /(?<=b(?1))xyz(b+)pqrstuvew/ /(a|bc)\1/SI /(a|bc)\1{2,3}/SI /(a|bc)(?1)/SI /(a|b\1)(a|b\1)/SI /(a|b\1){2}/SI /(a|bbbb\1)(a|bbbb\1)/SI /(a|bbbb\1){2}/SI /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/SI /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS "(?>.*/)foo"SI /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /xSI /(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/iSI /(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/SI /A)|(?
B))/I AB\Ca BA\Ca /(?|(?A)|(?B))/ /(?:a(? (?')|(?")) | b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/JIx a"aaaaa b"aaaaa ** Failers b"11111 a"11111 /^(?|(a)(b)(c)(?d)|(?e)) (?('D')X|Y)/JDZx abcdX eX ** Failers abcdY ey /(?a) (b)(c) (?d (?(R&A)$ | (?4)) )/JDZx abcdd ** Failers abcdde /abcd*/ xxxxabcd\P xxxxabcd\P\P /abcd*/i xxxxabcd\P xxxxabcd\P\P XXXXABCD\P XXXXABCD\P\P /abc\d*/ xxxxabc1\P xxxxabc1\P\P /(a)bc\1*/ xxxxabca\P xxxxabca\P\P /abc[de]*/ xxxxabcde\P xxxxabcde\P\P /-- This is not in the Perl >= 5.10 test because Perl seems currently to be broken and not behaving as specified in that it *does* bumpalong after hitting (*COMMIT). --/ /(?1)(A(*COMMIT)|B)D/ ABD XABD BAD ABXABD ** Failers ABX BAXBAD /(\3)(\1)(a)/ cat /(\3)(\1)(a)/SI cat /(\3)(\1)(a)/SI cat /i(?(DEFINE)(?a))/SI i /()i(?(1)a)/SI ia /(?i)a(?-i)b|c/BZ XabX XAbX CcC ** Failers XABX /(?i)a(?s)b|c/BZ /(?i)a(?s-i)b|c/BZ /^(ab(c\1)d|x){2}$/BZ xabcxd /^(?&t)*+(?(DEFINE)(?.))$/BZ /^(?&t)*(?(DEFINE)(?.))$/BZ / -- The first four of these are not in the Perl >= 5.10 test because Perl documents that the use of \K in assertions is "not well defined". The last is here because Perl gives the match as "b" rather than "ab". I believe this to be a Perl bug. --/ /(?=a\Kb)ab/ ab /(?!a\Kb)ac/ ac /^abc(?<=b\Kc)d/ abcd /^abc(?a\Kb)z|(ab)/ ab /----------------------/ /(?P(?P0|)|(?P>L2)(?P>L1))/ /abc(*MARK:)pqr/ /abc(*:)pqr/ /abc(*FAIL:123)xyz/ /--- This should, and does, fail. In Perl, it does not, which I think is a bug because replacing the B in the pattern by (B|D) does make it fail. ---/ /A(*COMMIT)B/+K ACABX /--- These should be different, but in Perl 5.11 are not, which I think is a bug in Perl. ---/ /A(*THEN)B|A(*THEN)C/K AC /A(*PRUNE)B|A(*PRUNE)C/K AC /--- This should fail; the SKIP advances by one, but when we get to AC, the PRUNE kills it. Perl behaves differently. ---/ /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC /--- Mark names can be duplicated. Perl doesn't give a mark for this one, though PCRE does. ---/ /^A(*:A)B|^X(*:A)Y/K ** Failers XAQQ /--- COMMIT at the start of a pattern should be the same as an anchor. Perl optimizations defeat this. So does the PCRE optimization unless we disable it with \Y. ---/ /(*COMMIT)ABC/ ABCDEFG ** Failers DEFGABC\Y /^(ab (c+(*THEN)cd) | xyz)/x abcccd /^(ab (c+(*PRUNE)cd) | xyz)/x abcccd /^(ab (c+(*FAIL)cd) | xyz)/x abcccd /--- Perl 5.11 gets some of these wrong ---/ /(?>.(*ACCEPT))*?5/ abcde /(.(*ACCEPT))*?5/ abcde /(.(*ACCEPT))5/ abcde /(.(*ACCEPT))*5/ abcde /A\NB./BZ ACBD *** Failers A\nB ACB\n /A\NB./sBZ ACBD ACB\n *** Failers A\nB /A\NB/ A\nB A\rB ** Failers A\r\nB /\R+b/BZ /\R+\n/BZ /\R+\d/BZ /\d*\R/BZ /\s*\R/BZ \x20\x0a \x20\x0d \x20\x0d\x0a /\S*\R/BZ a\x0a /X\h*\R/BZ X\x20\x0a /X\H*\R/BZ X\x0d\x0a /X\H+\R/BZ X\x0d\x0a /X\H++\R/BZ X\x0d\x0a /-- Perl treats this one differently, not failing the second string. I believe that is a bug in Perl. --/ /^((abc|abcx)(*THEN)y|abcd)/ abcd *** Failers abcxy /(?<=abc)def/ abc\P\P /abc$/ abc abc\P abc\P\P /abc$/m abc abc\n abc\P\P abc\n\P\P abc\P abc\n\P /abc\z/ abc abc\P abc\P\P /abc\Z/ abc abc\P abc\P\P /abc\b/ abc abc\P abc\P\P /abc\B/ abc abc\P abc\P\P /.+/ abc\>0 abc\>1 abc\>2 abc\>3 abc\>4 abc\>-4 /^\cÄ£/ /(?P(?P=abn)xxx)/BZ /(a\1z)/BZ /(?P(?P=abn)(?(?P=axn)xxx)/BZ /(?P(?P=axn)xxx)(?yy)/BZ /-- These tests are here because Perl gets the first one wrong. --/ /(\R*)(.)/s \r\n \r\r\n\n\r \r\r\n\n\r\n /(\R)*(.)/s \r\n \r\r\n\n\r \r\r\n\n\r\n /((?>\r\n|\n|\x0b|\f|\r|\x85)*)(.)/s \r\n \r\r\n\n\r \r\r\n\n\r\n /-- --/ /^abc$/BZ /^abc$/BZm /^(a)*+(\w)/S aaaaX ** Failers aaaa /^(?:a)*+(\w)/S aaaaX ** Failers aaaa /(a)++1234/SDZ /([abc])++1234/SI /(?<=(abc)+)X/ /(^ab)/I /(^ab)++/I /(^ab|^)+/I /(^ab|^)++/I /(?:^ab)/I /(?:^ab)++/I /(?:^ab|^)+/I /(?:^ab|^)++/I /(.*ab)/I /(.*ab)++/I /(.*ab|.*)+/I /(.*ab|.*)++/I /(?:.*ab)/I /(?:.*ab)++/I /(?:.*ab|.*)+/I /(?:.*ab|.*)++/I /(?=a)[bcd]/I /((?=a))[bcd]/I /((?=a))+[bcd]/I /((?=a))++[bcd]/I /(?=a+)[bcd]/iI /(?=a+?)[bcd]/iI /(?=a++)[bcd]/iI /(?=a{3})[bcd]/iI /(abc)\1+/S /-- Perl doesn't get these right IMO (the 3rd is PCRE-specific) --/ /(?1)(?:(b(*ACCEPT))){0}/ b /(?1)(?:(b(*ACCEPT))){0}c/ bc ** Failers b /(?1)(?:((*ACCEPT))){0}c/ c c\N /^.*?(?(?=a)a|b(*THEN)c)/ ba /^.*?(?(?=a)a|bc)/ ba /^.*?(?(?=a)a(*THEN)b|c)/ ac /^.*?(?(?=a)a(*THEN)b)c/ ac /^.*?(a(*THEN)b)c/ aabc /^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x aabc /^.*?(a(*THEN)b|z)c/ aabc /^.*?(z|a(*THEN)b)c/ aabc /-- --/ /-- These studied versions are here because they are not Perl-compatible; the studying means the mark is not seen. --/ /(*MARK:A)(*SKIP:B)(C|X)/KS C D /(*:A)A+(*SKIP:A)(B|Z)/KS AAAC /-- --/ "(?=a*(*ACCEPT)b)c" c c\N /(?1)c(?(DEFINE)((*ACCEPT)b))/ c c\N /(?>(*ACCEPT)b)c/ c c\N /(?:(?>(a)))+a%/++ %aa% /(a)b|ac/++SS ac\O3 /(a)(b)x|abc/++ abc\O6 /(a)bc|(a)(b)\2/ \O3abc \O4abc /(?(DEFINE)(a(?2)|b)(b(?1)|a))(?:(?1)|(?2))/SI /(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI /(a(?2)|b)(b(?1)|a)(?1)(?2)/SI /(abc)(?1)/SI /^(?>a)++/ aa\M aaaaaaaaa\M /(a)(?1)++/ aa\M aaaaaaaaa\M /(?:(foo)|(bar)|(baz))X/SS= bazfooX foobazbarX barfooX bazX foobarbazX bazfooX\O0 bazfooX\O2 bazfooX\O4 bazfooX\O6 bazfooX\O8 bazfooX\O10 /(?=abc){3}abc/BZ /(?=abc)+abc/BZ /(?=abc)++abc/BZ /(?=abc){0}xyz/BZ /(?=(a))?./BZ /(?=(a))??./BZ /^(?=(a)){0}b(?1)/BZ /(?(DEFINE)(a))?b(?1)/BZ /^(?=(?1))?[az]([abc])d/BZ /^(?!a){0}\w+/BZ /(?<=(abc))?xyz/BZ /[:a[:abc]b:]/BZ /((?2))((?1))/SS abc /((?(R2)a+|(?1)b))/SS aaaabcde /(?(R)a*(?1)|((?R))b)/SS aaaabcde /(a+|(?R)b)/ /^(a(*:A)(d|e(*:B))z|aeq)/C adz aez aeqwerty /.(*F)/ \P\Pabc /\btype\b\W*?\btext\b\W*?\bjavascript\b/IS /\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|a+)(?>(z+))\w/BZ aaaazzzzb ** Failers aazz /(.)(\1|a(?2))/ bab /\1|(.)(?R)\1/ cbbbc /(.)((?(1)c|a)|a(?2))/ baa /(?P(?P=abn)xxx)/BZ /(a\1z)/BZ /^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ \Maabbccddee /^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ \Maabbccddee /^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ \Maabbccddee /^a\x41z/ aAz *** Failers ax41z /^a[m\x41]z/ aAz /^a\x1z/ ax1z /^a\u0041z/ aAz *** Failers au0041z /^a[m\u0041]z/ aAz /^a\u041z/ au041z *** Failers aAz /^a\U0041z/ aU0041z *** Failers aAz /(?(?=c)c|d)++Y/BZ /(?(?=c)c|d)*+Y/BZ /a[\NB]c/ aNc /a[B-\Nc]/ /(a)(?2){0,1999}?(b)/ /(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/ /--- This test, with something more complicated than individual letters, causes different behaviour in Perl. Perhaps it disables some optimization; no tag is passed back for the failures, whereas in PCRE there is a tag. ---/ /(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK AABC XXYZ ** Failers XAQQ XAQQXZZ AXQQQ AXXQQQ /-- Perl doesn't give marks for these, though it does if the alternatives are replaced by single letters. --/ /(b|q)(*:m)f|a(*:n)w/K aw ** Failers abc /(q|b)(*:m)f|a(*:n)w/K aw ** Failers abc /-- After a partial match, the behaviour is as for a failure. --/ /^a(*:X)bcde/K abc\P /-- These are here because Perl doesn't return a mark, except for the first --/ /(?=(*:x))(q|)/K+ abc /(?=(*:x))((*:y)q|)/K+ abc /(?=(*:x))(?:(*:y)q|)/K+ abc /(?=(*:x))(?>(*:y)q|)/K+ abc /(?=a(*:x))(?!a(*:y)c)/K+ ab /(?=a(*:x))(?=a(*:y)c|)/K+ ab /(..)\1/ ab\P aba\P abab\P /(..)\1/i ab\P abA\P aBAb\P /(..)\1{2,}/ ab\P aba\P abab\P ababa\P ababab\P ababab\P\P abababa\P abababa\P\P /(..)\1{2,}/i ab\P aBa\P aBAb\P AbaBA\P abABAb\P aBAbaB\P\P abABabA\P abaBABa\P\P /(..)\1{2,}?x/i ab\P abA\P aBAb\P abaBA\P abAbaB\P abaBabA\P abAbABaBx\P /^(..)\1/ aba\P /^(..)\1{2,3}x/ aba\P ababa\P ababa\P\P abababx ababababx /^(..)\1{2,3}?x/ aba\P ababa\P ababa\P\P abababx ababababx /^(..)(\1{2,3})ab/ abababab /^\R/ \r\P \r\P\P /^\R{2,3}x/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P \r\rx \r\r\rx /^\R{2,3}?x/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P \r\rx \r\r\rx /^\R?x/ \r\P \r\P\P x \rx /^\R+x/ \r\P \r\P\P \r\n\P \r\n\P\P \rx /^a$/ a\r\P a\r\P\P /^a$/m a\r\P a\r\P\P /^(a$|a\r)/ a\r\P a\r\P\P /^(a$|a\r)/m a\r\P a\r\P\P /./ \r\P \r\P\P /.{2,3}/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /.{2,3}?/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /-- These two are here because Perl does not match: it seems to allow the COMMIT to escape from the assertion. --/ /(?=a(*COMMIT)b|ac)ac|ac/ ac /(?=a(*COMMIT)b|(ac)) ac | (a)c/x ac "AB(C(D))(E(F))?(?(?=\2)(?=\4))" ABCDGHI\O03 /-- This one is here because Perl does not confine the *COMMIT to the assertion, and therefore fails the entire subroutine call. --/ /((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ ac /-- End of testinput2 --/ pcre-8.31/testdata/testinput30000644000222100022210000000221111254137731013161 00000000000000/-- This set of tests checks local-specific features, using the fr_FR locale. It is not Perl-compatible. There is different version called wintestinput3 f or use on Windows, where the locale is called "french". --/ /^[\w]+/ *** Failers École /^[\w]+/Lfr_FR École /^[\w]+/ *** Failers École /^[\W]+/ École /^[\W]+/Lfr_FR *** Failers École /[\b]/ \b *** Failers a /[\b]/Lfr_FR \b *** Failers a /^\w+/ *** Failers École /^\w+/Lfr_FR École /(.+)\b(.+)/ École /(.+)\b(.+)/Lfr_FR *** Failers École /École/i École *** Failers école /École/iLfr_FR École école /\w/IS /\w/ISLfr_FR /^[\xc8-\xc9]/iLfr_FR École école /^[\xc8-\xc9]/Lfr_FR École *** Failers école /\W+/Lfr_FR >>>\xaa<<< >>>\xba<<< /[\W]+/Lfr_FR >>>\xaa<<< >>>\xba<<< /[^[:alpha:]]+/Lfr_FR >>>\xaa<<< >>>\xba<<< /\w+/Lfr_FR >>>\xaa<<< >>>\xba<<< /[\w]+/Lfr_FR >>>\xaa<<< >>>\xba<<< /[[:alpha:]]+/Lfr_FR >>>\xaa<<< >>>\xba<<< /[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR /-- End of testinput3 --/ pcre-8.31/testdata/testinput40000644000222100022210000003245711676645221013207 00000000000000/-- This set of tests is for UTF support, excluding Unicode properties. It is compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit PCRE libraries. --/ /a.b/8 acb a\x7fb a\x{100}b *** Failers a\nb /a(.{3})b/8 a\x{4000}xyb a\x{4000}\x7fyb a\x{4000}\x{100}yb *** Failers a\x{4000}b ac\ncb /a(.*?)(.)/ a\xc0\x88b /a(.*?)(.)/8 a\x{100}b /a(.*)(.)/ a\xc0\x88b /a(.*)(.)/8 a\x{100}b /a(.)(.)/ a\xc0\x92bcd /a(.)(.)/8 a\x{240}bcd /a(.?)(.)/ a\xc0\x92bcd /a(.?)(.)/8 a\x{240}bcd /a(.??)(.)/ a\xc0\x92bcd /a(.??)(.)/8 a\x{240}bcd /a(.{3})b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b *** Failers a\x{1234}b ac\ncb /a(.{3,})b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b *** Failers a\x{1234}b /a(.{3,}?)b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b *** Failers a\x{1234}b /a(.{3,5})b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b axbxxbcdefghijb axxxxxbcdefghijb *** Failers a\x{1234}b axxxxxxbcdefghijb /a(.{3,5}?)b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b axbxxbcdefghijb axxxxxbcdefghijb *** Failers a\x{1234}b axxxxxxbcdefghijb /^[a\x{c0}]/8 *** Failers \x{100} /(?<=aXb)cd/8 aXbcd /(?<=a\x{100}b)cd/8 a\x{100}bcd /(?<=a\x{100000}b)cd/8 a\x{100000}bcd /(?:\x{100}){3}b/8 \x{100}\x{100}\x{100}b *** Failers \x{100}\x{100}b /\x{ab}/8 \x{ab} \xc2\xab *** Failers \x00{ab} /(?<=(.))X/8 WXYZ \x{256}XYZ *** Failers XYZ /[^a]+/8g bcd \x{100}aY\x{256}Z /^[^a]{2}/8 \x{100}bc /^[^a]{2,}/8 \x{100}bcAa /^[^a]{2,}?/8 \x{100}bca /[^a]+/8ig bcd \x{100}aY\x{256}Z /^[^a]{2}/8i \x{100}bc /^[^a]{2,}/8i \x{100}bcAa /^[^a]{2,}?/8i \x{100}bca /\x{100}{0,0}/8 abcd /\x{100}?/8 abcd \x{100}\x{100} /\x{100}{0,3}/8 \x{100}\x{100} \x{100}\x{100}\x{100}\x{100} /\x{100}*/8 abce \x{100}\x{100}\x{100}\x{100} /\x{100}{1,1}/8 abcd\x{100}\x{100}\x{100}\x{100} /\x{100}{1,3}/8 abcd\x{100}\x{100}\x{100}\x{100} /\x{100}+/8 abcd\x{100}\x{100}\x{100}\x{100} /\x{100}{3}/8 abcd\x{100}\x{100}\x{100}XX /\x{100}{3,5}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX /\x{100}{3,}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX /(?<=a\x{100}{2}b)X/8+ Xyyya\x{100}\x{100}bXzzz /\D*/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /\D*/8 \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /\D/8 1X2 1\x{100}2 />\S/8 > >X Y > >\x{100} Y /\d/8 \x{100}3 /\s/8 \x{100} X /\D+/8 12abcd34 *** Failers 1234 /\D{2,3}/8 12abcd34 12ab34 *** Failers 1234 12a34 /\D{2,3}?/8 12abcd34 12ab34 *** Failers 1234 12a34 /\d+/8 12abcd34 *** Failers /\d{2,3}/8 12abcd34 1234abcd *** Failers 1.4 /\d{2,3}?/8 12abcd34 1234abcd *** Failers 1.4 /\S+/8 12abcd34 *** Failers \ \ /\S{2,3}/8 12abcd34 1234abcd *** Failers \ \ /\S{2,3}?/8 12abcd34 1234abcd *** Failers \ \ />\s+ <34 *** Failers />\s{2,3} \s{2,3}? \xff< /[\xff]/8 >\x{ff}< /[^\xFF]/ XYZ /[^\xff]/8 XYZ \x{123} /^[ac]*b/8 xb /^[ac\x{100}]*b/8 xb /^[^x]*b/8i xb /^[^x]*b/8 xb /^\d*b/8 xb /(|a)/g8 catac a\x{256}a /^\x{85}$/8i \x{85} /^ሴ/8 ሴ /^\ሴ/8 ሴ "(?s)(.{1,5})"8 abcdefg ab /a*\x{100}*\w/8 a /\S\S/8g A\x{a3}BC /\S{2}/8g A\x{a3}BC /\W\W/8g +\x{a3}== /\W{2}/8g +\x{a3}== /\S/8g \x{442}\x{435}\x{441}\x{442} /[\S]/8g \x{442}\x{435}\x{441}\x{442} /\D/8g \x{442}\x{435}\x{441}\x{442} /[\D]/8g \x{442}\x{435}\x{441}\x{442} /\W/8g \x{2442}\x{2435}\x{2441}\x{2442} /[\W]/8g \x{2442}\x{2435}\x{2441}\x{2442} /[\S\s]*/8 abc\n\r\x{442}\x{435}\x{441}\x{442}xyz /[\x{41f}\S]/8g \x{442}\x{435}\x{441}\x{442} /.[^\S]./8g abc def\x{442}\x{443}xyz\npqr /.[^\S\n]./8g abc def\x{442}\x{443}xyz\npqr /[[:^alnum:]]/8g +\x{2442} /[[:^alpha:]]/8g +\x{2442} /[[:^ascii:]]/8g A\x{442} /[[:^blank:]]/8g A\x{442} /[[:^cntrl:]]/8g A\x{442} /[[:^digit:]]/8g A\x{442} /[[:^graph:]]/8g \x19\x{e01ff} /[[:^lower:]]/8g A\x{422} /[[:^print:]]/8g \x{19}\x{e01ff} /[[:^punct:]]/8g A\x{442} /[[:^space:]]/8g A\x{442} /[[:^upper:]]/8g a\x{442} /[[:^word:]]/8g +\x{2442} /[[:^xdigit:]]/8g M\x{442} /[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞĀĂĄĆĈĊČĎÄĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿÅŃŅŇŊŌŎÅÅ’Å”Å–Å˜ÅšÅœÅžÅ Å¢Å¤Å¦Å¨ÅªÅ¬Å®Å°Å²Å´Å¶Å¸Å¹Å»Å½ÆÆ‚Æ„Æ†Æ‡Æ‰ÆŠÆ‹ÆŽÆÆÆ‘Æ“Æ”Æ–Æ—Æ˜ÆœÆÆŸÆ Æ¢Æ¤Æ¦Æ§Æ©Æ¬Æ®Æ¯Æ±Æ²Æ³ÆµÆ·Æ¸Æ¼Ç„LJNJÇÇǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎÈȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾÉΆΈΉΊΌΎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀÐЂЃЄЅІЇЈЉЊЋЌÐÐŽÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎÒҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀÓÓƒÓ…Ó‡Ó‰Ó‹ÓÓӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀÕÕ‚ÕƒÕ„Õ…Õ†Õ‡ÕˆÕ‰ÕŠÕ‹ÕŒÕÕŽÕÕՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀáƒáƒ‚ჃჄჅḀḂḄḆḈḊḌḎá¸á¸’ḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎá¹á¹’ṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎáºáº’ẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎá»á»’ỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌá¼á¼Žá¼á¼˜á¼™á¼šá¼›á¼œá¼á¼¨á¼©á¼ªá¼«á¼¬á¼­á¼®á¼¯á¼¸á¼¹á¼ºá¼»á¼¼á¼½á¼¾á¼¿á½ˆá½‰á½Šá½‹á½Œá½á½™á½›á½á½Ÿá½¨á½©á½ªá½«á½¬á½­á½®á½¯á¾¸á¾¹á¾ºá¾»á¿ˆá¿‰á¿Šá¿‹á¿˜á¿™á¿šá¿›á¿¨á¿©á¿ªá¿«á¿¬á¿¸á¿¹á¿ºá¿»abcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿÄăąćĉċÄÄđēĕėęěÄğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋÅÅőœŕŗřśÅÅŸÅ¡Å£Å¥Å§Å©Å«Å­Å¯Å±Å³ÅµÅ·ÅºÅ¼Å¾Å¿Æ€ÆƒÆ…ÆˆÆŒÆÆ’ƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎÇǒǔǖǘǚǜÇǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿÈȃȅȇȉȋÈÈȑȓȕȗșțÈȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀÉɑɒɓɔɕɖɗɘəɚɛɜÉɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀÊʂʃʄʅʆʇʈʉʊʋʌÊÊŽÊÊʑʒʓʔʕʖʗʘʙʚʛʜÊʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯÎάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏÏŽÏϑϕϖϗϙϛÏϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑёђѓєѕіїјљњћќÑўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿÒÒ‹ÒÒÒ‘Ò“Ò•Ò—Ò™Ò›ÒҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛÓÓŸÓ¡Ó£Ó¥Ó§Ó©Ó«Ó­Ó¯Ó±Ó³ÓµÓ·Ó¹ÔÔƒÔ…Ô‡Ô‰Ô‹ÔÔÕ¡Õ¢Õ£Õ¤Õ¥Õ¦Õ§Õ¨Õ©ÕªÕ«Õ¬Õ­Õ®Õ¯Õ°Õ±Õ²Õ³Õ´ÕµÕ¶Õ·Õ¸Õ¹ÕºÕ»Õ¼Õ½Õ¾Õ¿Ö€Öւփքօֆևᴀá´á´‚ᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌá´á´Žá´á´á´‘ᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜá´á´žá´Ÿá´ á´¡á´¢á´£á´¤á´¥á´¦á´§á´¨á´©á´ªá´«áµ¢áµ£áµ¤áµ¥áµ¦áµ§áµ¨áµ©áµªáµ«áµ¬áµ­áµ®áµ¯áµ°áµ±áµ²áµ³áµ´áµµáµ¶áµ·áµ¹áµºáµ»áµ¼áµ½áµ¾áµ¿á¶€á¶á¶‚ᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌá¶á¶Žá¶á¶á¶‘ᶒᶓᶔᶕᶖᶗᶘᶙᶚá¸á¸ƒá¸…ḇḉḋá¸á¸á¸‘ḓḕḗḙḛá¸á¸Ÿá¸¡á¸£á¸¥á¸§á¸©á¸«á¸­á¸¯á¸±á¸³á¸µá¸·á¸¹á¸»á¸½á¸¿á¹á¹ƒá¹…ṇṉṋá¹á¹á¹‘ṓṕṗṙṛá¹á¹Ÿá¹¡á¹£á¹¥á¹§á¹©á¹«á¹­á¹¯á¹±á¹³á¹µá¹·á¹¹á¹»á¹½á¹¿áºáºƒáº…ẇẉẋáºáºáº‘ẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếá»á»ƒá»…ệỉịá»á»á»‘ồổỗộớá»á»Ÿá»¡á»£á»¥á»§á»©á»«á»­á»¯á»±á»³á»µá»·á»¹á¼€á¼á¼‚ἃἄἅἆἇá¼á¼‘ἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀá½á½‚ὃὄὅá½á½‘ὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀá¾á¾‚ᾃᾄᾅᾆᾇá¾á¾‘ᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇá¿á¿‘ῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷâ²â²ƒâ²…ⲇⲉⲋâ²â²â²‘ⲓⲕⲗⲙⲛâ²â²Ÿâ²¡â²£â²¥â²§â²©â²«â²­â²¯â²±â²³â²µâ²·â²¹â²»â²½â²¿â³â³ƒâ³…ⳇⳉⳋâ³â³â³‘ⳓⳕⳗⳙⳛâ³â³Ÿâ³¡â³£â³¤â´€â´â´‚ⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌâ´â´Žâ´â´â´‘ⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜâ´â´žâ´Ÿâ´ â´¡â´¢â´£â´¤â´¥ï¬€ï¬ï¬‚ffifflſtstﬓﬔﬕﬖﬗ\d-_^]/8 /^[^d]*?$/ abc /^[^d]*?$/8 abc /^[^d]*?$/i abc /^[^d]*?$/8i abc /(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]/8 /^[a\x{c0}]b/8 \x{c0}b /^([a\x{c0}]*?)aa/8 a\x{c0}aaaa/ /^([a\x{c0}]*?)aa/8 a\x{c0}aaaa/ a\x{c0}a\x{c0}aaa/ /^([a\x{c0}]*)aa/8 a\x{c0}aaaa/ a\x{c0}a\x{c0}aaa/ /^([a\x{c0}]*)a\x{c0}/8 a\x{c0}aaaa/ a\x{c0}a\x{c0}aaa/ /A*/g8 AAB\x{123}BAA /(abc)\1/8i abc /(abc)\1/8 abc /a(*:a\x{1234}b)/8K abc /a(*:a£b)/8K abc /-- End of testinput4 --/ pcre-8.31/testdata/testinput50000644000222100022210000002644311767404437013211 00000000000000/-- This set of tests checks the API, internals, and non-Perl stuff for UTF support, excluding Unicode properties. However, tests that give different results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/ /\x{110000}/8DZ /\x{ffffffff}/8 /\x{100000000}/8 /\x{d800}/8 /\x{dfff}/8 /\x{d7ff}/8 /\x{e000}/8 /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd /\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 \x{0041}\x{2262}\x{0391}\x{002e} /.{3,5}X/DZ8 \x{212ab}\x{212ab}\x{212ab}\x{861}X /.{3,5}?/DZ8 \x{212ab}\x{212ab}\x{212ab}\x{861} /(?<=\C)X/8 Should produce an error diagnostic /^[ab]/8DZ bar *** Failers c \x{ff} \x{100} /^[^ab]/8DZ c \x{ff} \x{100} *** Failers aaa /\x{100}*(\d+|"(?1)")/8 1234 "1234" \x{100}1234 "\x{100}1234" \x{100}\x{100}12ab \x{100}\x{100}"12" *** Failers \x{100}\x{100}abcd /\x{100}*/8DZ /a\x{100}*/8DZ /ab\x{100}*/8DZ /\x{100}*A/8DZ A /\x{100}*\d(?R)/8DZ /[Z\x{100}]/8DZ Z\x{100} \x{100} \x{100}Z *** Failers /[\x{200}-\x{100}]/8 /[Ä€-Ä„]/8 \x{100} \x{104} *** Failers \x{105} \x{ff} /[z-\x{100}]/8DZ /[z\Qa-d]Ä€\E]/8DZ \x{100} Ä€ /[\xFF]/DZ >\xff< /[^\xFF]/DZ /[Ä-Ü]/8 Ö # Matches without Study \x{d6} /[Ä-Ü]/8S Ö <-- Same with Study \x{d6} /[\x{c4}-\x{dc}]/8 Ö # Matches without Study \x{d6} /[\x{c4}-\x{dc}]/8S Ö <-- Same with Study \x{d6} /[^\x{100}]abc(xyz(?1))/8DZ /[ab\x{100}]abc(xyz(?1))/8DZ /(\x{100}(b(?2)c))?/DZ8 /(\x{100}(b(?2)c)){0,2}/DZ8 /(\x{100}(b(?1)c))?/DZ8 /(\x{100}(b(?1)c)){0,2}/DZ8 /\W/8 A.B A\x{100}B /\w/8 \x{100}X /^\ሴ/8DZ /\x{100}*\d/8DZ /\x{100}*\s/8DZ /\x{100}*\w/8DZ /\x{100}*\D/8DZ /\x{100}*\S/8DZ /\x{100}*\W/8DZ /()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() A (x) (?41) B/8x AxxB /^[\x{100}\E-\Q\E\x{150}]/BZ8 /^[\QÄ€\E-\QÅ\E]/BZ8 /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK /abc.$/mgx8 abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 /^a\Rb/8 a\nb a\rb a\r\nb a\x0bb a\x0cb a\x{85}b a\x{2028}b a\x{2029}b ** Failers a\n\rb /^a\R*b/8 ab a\nb a\rb a\r\nb a\x0bb a\x0c\x{2028}\x{2029}b a\x{85}b a\n\rb a\n\r\x{85}\x0cb /^a\R+b/8 a\nb a\rb a\r\nb a\x0bb a\x0c\x{2028}\x{2029}b a\x{85}b a\n\rb a\n\r\x{85}\x0cb ** Failers ab /^a\R{1,3}b/8 a\nb a\n\rb a\n\r\x{85}b a\r\n\r\nb a\r\n\r\n\r\nb a\n\r\n\rb a\n\n\r\nb ** Failers a\n\n\n\rb a\r /\H\h\V\v/8 X X\x0a X\x09X\x0b ** Failers \x{a0} X\x0a /\H*\h+\V?\v{3,4}/8 \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a \x09\x20\x{a0}\x0a\x0b\x0c ** Failers \x09\x20\x{a0}\x0a\x0b /\H\h\V\v/8 \x{3001}\x{3000}\x{2030}\x{2028} X\x{180e}X\x{85} ** Failers \x{2009} X\x0a /\H*\h+\V?\v{3,4}/8 \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a \x09\x20\x{202f}\x0a\x0b\x0c ** Failers \x09\x{200a}\x{a0}\x{2028}\x0b /[\h]/8BZ >\x{1680} /[\h]{3,}/8BZ >\x{1680}\x{180e}\x{2000}\x{2003}\x{200a}\x{202f}\x{205f}\x{3000}< /[\v]/8BZ /[\H]/8BZ /[\V]/8BZ /.*$/8 \x{1ec5} /a\Rb/I8 a\rb a\nb a\r\nb ** Failers a\x{85}b a\x0bb /a\Rb/I8 a\rb a\nb a\r\nb a\x{85}b a\x0bb ** Failers a\x{85}b\ a\x0bb\ /a\R?b/I8 a\rb a\nb a\r\nb ** Failers a\x{85}b a\x0bb /a\R?b/I8 a\rb a\nb a\r\nb a\x{85}b a\x0bb ** Failers a\x{85}b\ a\x0bb\ /.*a.*=.b.*/8 QQQ\x{2029}ABCaXYZ=!bPQR ** Failers a\x{2029}b \x61\xe2\x80\xa9\x62 /[[:a\x{100}b:]]/8 /a[^]b/8 a\x{1234}b a\nb ** Failers ab /a[^]+b/8 aXb a\nX\nX\x{1234}b ** Failers ab /(\x{de})\1/ \x{de}\x{de} /X/8f A\x{1ec5}ABCXYZ /Xa{2,4}b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /Xa{2,4}?b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /Xa{2,4}+b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X\x{123}{2,4}b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X\x{123}{2,4}?b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X\x{123}{2,4}+b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X\x{123}{2,4}b/8 Xx\P X\x{123}x\P X\x{123}\x{123}x\P X\x{123}\x{123}\x{123}x\P X\x{123}\x{123}\x{123}\x{123}x\P /X\x{123}{2,4}?b/8 Xx\P X\x{123}x\P X\x{123}\x{123}x\P X\x{123}\x{123}\x{123}x\P X\x{123}\x{123}\x{123}\x{123}x\P /X\x{123}{2,4}+b/8 Xx\P X\x{123}x\P X\x{123}\x{123}x\P X\x{123}\x{123}\x{123}x\P X\x{123}\x{123}\x{123}\x{123}x\P /X\d{2,4}b/8 X\P X3\P X33\P X333\P X3333\P /X\d{2,4}?b/8 X\P X3\P X33\P X333\P X3333\P /X\d{2,4}+b/8 X\P X3\P X33\P X333\P X3333\P /X\D{2,4}b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X\D{2,4}?b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X\D{2,4}+b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X\D{2,4}b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X\D{2,4}?b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X\D{2,4}+b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X[abc]{2,4}b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X[abc]{2,4}?b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X[abc]{2,4}+b/8 X\P Xa\P Xaa\P Xaaa\P Xaaaa\P /X[abc\x{123}]{2,4}b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X[abc\x{123}]{2,4}?b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X[abc\x{123}]{2,4}+b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X[^a]{2,4}b/8 X\P Xz\P Xzz\P Xzzz\P Xzzzz\P /X[^a]{2,4}?b/8 X\P Xz\P Xzz\P Xzzz\P Xzzzz\P /X[^a]{2,4}+b/8 X\P Xz\P Xzz\P Xzzz\P Xzzzz\P /X[^a]{2,4}b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X[^a]{2,4}?b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /X[^a]{2,4}+b/8 X\P X\x{123}\P X\x{123}\x{123}\P X\x{123}\x{123}\x{123}\P X\x{123}\x{123}\x{123}\x{123}\P /(Y)X\1{2,4}b/8 YX\P YXY\P YXYY\P YXYYY\P YXYYYY\P /(Y)X\1{2,4}?b/8 YX\P YXY\P YXYY\P YXYYY\P YXYYYY\P /(Y)X\1{2,4}+b/8 YX\P YXY\P YXYY\P YXYYY\P YXYYYY\P /(\x{123})X\1{2,4}b/8 \x{123}X\P \x{123}X\x{123}\P \x{123}X\x{123}\x{123}\P \x{123}X\x{123}\x{123}\x{123}\P \x{123}X\x{123}\x{123}\x{123}\x{123}\P /(\x{123})X\1{2,4}?b/8 \x{123}X\P \x{123}X\x{123}\P \x{123}X\x{123}\x{123}\P \x{123}X\x{123}\x{123}\x{123}\P \x{123}X\x{123}\x{123}\x{123}\x{123}\P /(\x{123})X\1{2,4}+b/8 \x{123}X\P \x{123}X\x{123}\P \x{123}X\x{123}\x{123}\P \x{123}X\x{123}\x{123}\x{123}\P \x{123}X\x{123}\x{123}\x{123}\x{123}\P /\bthe cat\b/8 the cat\P the cat\P\P /abcd*/8 xxxxabcd\P xxxxabcd\P\P /abcd*/i8 xxxxabcd\P xxxxabcd\P\P XXXXABCD\P XXXXABCD\P\P /abc\d*/8 xxxxabc1\P xxxxabc1\P\P /(a)bc\1*/8 xxxxabca\P xxxxabca\P\P /abc[de]*/8 xxxxabcde\P xxxxabcde\P\P /X\W{3}X/8 \PX /\sxxx\s/8T1 AB\x{85}xxx\x{a0}XYZ AB\x{a0}xxx\x{85}XYZ /\S \S/8T1 \x{a2} \x{84} 'A#хц'8xBZ 'A#хц PQ'8xBZ /a+#Ñ…aa z#XX?/8xBZ /a+#Ñ…aa z#Ñ…?/8xBZ /\g{A}xxx#bXX(?'A'123) (?'A'456)/8xBZ /\g{A}xxx#bÑ…(?'A'123) (?'A'456)/8xBZ /^\cÄ£/8 /(\R*)(.)/s8 \r\n \r\r\n\n\r \r\r\n\n\r\n /(\R)*(.)/s8 \r\n \r\r\n\n\r \r\r\n\n\r\n /[^\x{1234}]+/iS8I /[^\x{1234}]+?/iS8I /[^\x{1234}]++/iS8I /[^\x{1234}]{2}/iS8I // /f.*/ \P\Pfor /f.*/s \P\Pfor /f.*/8 \P\Pfor /f.*/8s \P\Pfor /\x{d7ff}\x{e000}/8 /\x{d800}/8 /\x{dfff}/8 /\h+/8 \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} /[\h\x{e000}]+/8BZ \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} /\H+/8 \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} /[\H\x{d7ff}]+/8BZ \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} /\v+/8 \x{2027}\x{2030}\x{2028}\x{2029} \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d /[\v\x{e000}]+/8BZ \x{2027}\x{2030}\x{2028}\x{2029} \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d /\V+/8 \x{2028}\x{2029}\x{2027}\x{2030} \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} /[\V\x{d7ff}]+/8BZ \x{2028}\x{2029}\x{2027}\x{2030} \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} /\R+/8 \x{2027}\x{2030}\x{2028}\x{2029} \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d /(..)\1/8 ab\P aba\P abab\P /(..)\1/8i ab\P abA\P aBAb\P /(..)\1{2,}/8 ab\P aba\P abab\P ababa\P ababab\P ababab\P\P abababa\P abababa\P\P /(..)\1{2,}/8i ab\P aBa\P aBAb\P AbaBA\P abABAb\P aBAbaB\P\P abABabA\P abaBABa\P\P /(..)\1{2,}?x/8i ab\P abA\P aBAb\P abaBA\P abAbaB\P abaBabA\P abAbABaBx\P /./8 \r\P \r\P\P /.{2,3}/8 \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /.{2,3}?/8 \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ /[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi /[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ /[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi /(?<=\x{1234}\x{1234})\bxy/I8 /(?8BZ /[\u0100-\u0200]/8BZ /\ud800/8 /-- End of testinput5 --/ pcre-8.31/testdata/testinput60000644000222100022210000003040511723162171013167 00000000000000/-- This set of tests is for Unicode property support. It is compatible with Perl >= 5.10, but not 5.8 because it tests some extra properties that are not in the earlier release. --/ /^\pC\pL\pM\pN\pP\pS\pZ\s+/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} /^>\pZ+/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} /^>[[:space:]]*/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} /^>[[:blank:]]*/8W >\x{20}\x{a0}\x{1680}\x{180e}\x{2000}\x{202f}\x{9}\x{b}\x{2028} /^[[:alpha:]]*/8W Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d} /^[[:alnum:]]*/8W Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d}1\x{660}\x{bef}\x{16ee} /^[[:cntrl:]]*/8W \x{0}\x{09}\x{1f}\x{7f}\x{9f} /^[[:graph:]]*/8W A\x{a1}\x{a0} /^[[:print:]]*/8W A z\x{a0}\x{a1} /^[[:punct:]]*/8W .+\x{a1}\x{a0} /\p{Zs}*?\R/ ** Failers a\xFCb /\p{Zs}*\R/ ** Failers a\xFCb /â±¥/8i â±¥ Ⱥx Ⱥ /[â±¥]/8i â±¥ Ⱥx Ⱥ /Ⱥ/8i Ⱥ â±¥ /-- End of testinput6 --/ pcre-8.31/testdata/testinput70000644000222100022210000002151311762204127013171 00000000000000/-- These tests for Unicode property support test PCRE's API and show some of the compiled code. They are not Perl-compatible. --/ /[\p{L}]/DZ /[\p{^L}]/DZ /[\P{L}]/DZ /[\P{^L}]/DZ /[abc\p{L}\x{0660}]/8DZ /[\p{Nd}]/8DZ 1234 /[\p{Nd}+-]+/8DZ 1234 12-34 12+\x{661}-34 ** Failers abcd /[\x{105}-\x{109}]/8iDZ \x{104} \x{105} \x{109} ** Failers \x{100} \x{10a} /[z-\x{100}]/8iDZ Z z \x{39c} \x{178} | \x{80} \x{ff} \x{100} \x{101} ** Failers \x{102} Y y /[z-\x{100}]/8DZi /(?:[\PPa*]*){8,}/ /[\P{Any}]/BZ /[\P{Any}\E]/BZ /(\P{Yi}+\277)/ /(\P{Yi}+\277)?/ /(?<=\P{Yi}{3}A)X/ /\p{Yi}+(\P{Yi}+)(?1)/ /(\P{Yi}{2}\277)?/ /[\P{Yi}A]/ /[\P{Yi}\P{Yi}\P{Yi}A]/ /[^\P{Yi}A]/ /[^\P{Yi}\P{Yi}\P{Yi}A]/ /(\P{Yi}*\277)*/ /(\P{Yi}*?\277)*/ /(\p{Yi}*+\277)*/ /(\P{Yi}?\277)*/ /(\P{Yi}??\277)*/ /(\p{Yi}?+\277)*/ /(\P{Yi}{0,3}\277)*/ /(\P{Yi}{0,3}?\277)*/ /(\p{Yi}{0,3}+\277)*/ /\p{Zl}{2,3}+/8BZ \xe2\x80\xa8\xe2\x80\xa8 \x{2028}\x{2028}\x{2028} /\p{Zl}/8BZ /\p{Lu}{3}+/8BZ /\pL{2}+/8BZ /\p{Cc}{2}+/8BZ /^\p{Cs}/8 \?\x{dfff} ** Failers \x{09f} /^\p{Sc}+/8 $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} \x{9f2} ** Failers X \x{2c2} /^\p{Zs}/8 \ \ \x{a0} \x{1680} \x{180e} \x{2000} \x{2001} ** Failers \x{2028} \x{200d} /-- These four are here rather than in test 6 because Perl has problems with the negative versions of the properties. --/ /\p{^Lu}/8i 1234 ** Failers ABC /\P{Lu}/8i 1234 ** Failers ABC /\p{Ll}/8i a Az ** Failers ABC /\p{Lu}/8i A a\x{10a0}B ** Failers a \x{1d00} /[\x{c0}\x{391}]/8i \x{c0} \x{e0} /-- The next two are special cases where the lengths of the different cases of the same character differ. The first went wrong with heap frame storage; the second was broken in all cases. --/ /^\x{023a}+?(\x{0130}+)/8i \x{023a}\x{2c65}\x{0130} /^\x{023a}+([^X])/8i \x{023a}\x{2c65}X /\x{c0}+\x{116}+/8i \x{c0}\x{e0}\x{116}\x{117} /[\x{c0}\x{116}]+/8i \x{c0}\x{e0}\x{116}\x{117} /(\x{de})\1/8i \x{de}\x{de} \x{de}\x{fe} \x{fe}\x{fe} \x{fe}\x{de} /^\x{c0}$/8i \x{c0} \x{e0} /^\x{e0}$/8i \x{c0} \x{e0} /-- The next two should be Perl-compatible, but it fails to match \x{e0}. PCRE will match it only with UCP support, because without that it has no notion of case for anything other than the ASCII letters. --/ /((?i)[\x{c0}])/8 \x{c0} \x{e0} /(?i:[\x{c0}])/8 \x{c0} \x{e0} /-- This should be Perl-compatible but Perl 5.11 gets \x{300} wrong. --/8 /^\X/8 A A\x{300}BC A\x{300}\x{301}\x{302}BC *** Failers \x{300} /-- These are PCRE's extra properties to help with Unicodizing \d etc. --/ /^\p{Xan}/8 ABCD 1234 \x{6ca} \x{a6c} \x{10a7} ** Failers _ABC /^\p{Xan}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ ** Failers _ABC /^\p{Xan}+?/8 \x{6ca}\x{a6c}\x{10a7}_ /^\p{Xan}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xan}{2,9}/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xan}{2,9}?/8 \x{6ca}\x{a6c}\x{10a7}_ /^[\p{Xan}]/8 ABCD1234_ 1234abcd_ \x{6ca} \x{a6c} \x{10a7} ** Failers _ABC /^[\p{Xan}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ ** Failers _ABC /^>\p{Xsp}/8 >\x{1680}\x{2028}\x{0b} >\x{a0} ** Failers \x{0b} /^>\p{Xsp}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}+?/8 >\x{1680}\x{2028}\x{0b} /^>\p{Xsp}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>[\p{Xsp}]/8 >\x{2028}\x{0b} /^>[\p{Xsp}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}/8 >\x{1680}\x{2028}\x{0b} >\x{a0} ** Failers \x{0b} /^>\p{Xps}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}+?/8 >\x{1680}\x{2028}\x{0b} /^>\p{Xps}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>[\p{Xps}]/8 >\x{2028}\x{0b} /^>[\p{Xps}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^\p{Xwd}/8 ABCD 1234 \x{6ca} \x{a6c} \x{10a7} _ABC ** Failers [] /^\p{Xwd}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xwd}+?/8 \x{6ca}\x{a6c}\x{10a7}_ /^\p{Xwd}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xwd}{2,9}/8 A_B12\x{6ca}\x{a6c}\x{10a7} /^\p{Xwd}{2,9}?/8 \x{6ca}\x{a6c}\x{10a7}_ /^[\p{Xwd}]/8 ABCD1234_ 1234abcd_ \x{6ca} \x{a6c} \x{10a7} _ABC ** Failers [] /^[\p{Xwd}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /-- A check not in UTF-8 mode --/ /^[\p{Xwd}]+/ ABCD1234_ /-- Some negative checks --/ /^[\P{Xwd}]+/8 !.+\x{019}\x{35a}AB /^[\p{^Xwd}]+/8 !.+\x{019}\x{35a}AB /[\D]/WBZ8 1\x{3c8}2 /[\d]/WBZ8 >\x{6f4}< /[\S]/WBZ8 \x{1680}\x{6f4}\x{1680} /[\s]/WBZ8 >\x{1680}< /[\W]/WBZ8 A\x{1712}B /[\w]/WBZ8 >\x{1723}< /\D/WBZ8 1\x{3c8}2 /\d/WBZ8 >\x{6f4}< /\S/WBZ8 \x{1680}\x{6f4}\x{1680} /\s/WBZ8 >\x{1680}> /\W/WBZ8 A\x{1712}B /\w/WBZ8 >\x{1723}< /[[:alpha:]]/WBZ /[[:lower:]]/WBZ /[[:upper:]]/WBZ /[[:alnum:]]/WBZ /[[:ascii:]]/WBZ /[[:cntrl:]]/WBZ /[[:digit:]]/WBZ /[[:graph:]]/WBZ /[[:print:]]/WBZ /[[:punct:]]/WBZ /[[:space:]]/WBZ /[[:word:]]/WBZ /[[:xdigit:]]/WBZ /-- Unicode properties for \b abd \B --/ /\b...\B/8W abc_ \x{37e}abc\x{376} \x{37e}\x{376}\x{371}\x{393}\x{394} !\x{c0}++\x{c1}\x{c2} !\x{c0}+++++ /-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ /\b...\B/8 abc_ ** Failers \x{37e}abc\x{376} \x{37e}\x{376}\x{371}\x{393}\x{394} !\x{c0}++\x{c1}\x{c2} !\x{c0}+++++ /-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ /\b...\B/W abc_ !\x{c0}++\x{c1}\x{c2} !\x{c0}+++++ /-- Some of these are silly, but they check various combinations --/ /[[:^alpha:][:^cntrl:]]+/8WBZ 123 abc /[[:^cntrl:][:^alpha:]]+/8WBZ 123 abc /[[:alpha:]]+/8WBZ abc /[[:^alpha:]\S]+/8WBZ 123 abc /[^\d]+/8WBZ abc123 abc\x{123} \x{660}abc /\p{Lu}+9\p{Lu}+B\p{Lu}+b/BZ /\p{^Lu}+9\p{^Lu}+B\p{^Lu}+b/BZ /\P{Lu}+9\P{Lu}+B\P{Lu}+b/BZ /\p{Han}+X\p{Greek}+\x{370}/BZ8 /\p{Xan}+!\p{Xan}+A/BZ /\p{Xsp}+!\p{Xsp}\t/BZ /\p{Xps}+!\p{Xps}\t/BZ /\p{Xwd}+!\p{Xwd}_/BZ /A+\p{N}A+\dB+\p{N}*B+\d*/WBZ /-- These behaved oddly in Perl, so they are kept in this test --/ /(\x{23a}\x{23a}\x{23a})?\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} /(ȺȺȺ)?\1/8i ȺȺȺⱥⱥ /(\x{23a}\x{23a}\x{23a})?\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} /(ȺȺȺ)?\1/8i ȺȺȺⱥⱥⱥ /(\x{23a}\x{23a}\x{23a})\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} /(ȺȺȺ)\1/8i ȺȺȺⱥⱥ /(\x{23a}\x{23a}\x{23a})\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} /(ȺȺȺ)\1/8i ȺȺȺⱥⱥⱥ /(\x{2c65}\x{2c65})\1/8i \x{2c65}\x{2c65}\x{23a}\x{23a} /(ⱥⱥ)\1/8i ⱥⱥȺȺ /(\x{23a}\x{23a}\x{23a})\1Y/8i X\x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}YZ /(\x{2c65}\x{2c65})\1Y/8i X\x{2c65}\x{2c65}\x{23a}\x{23a}YZ /-- --/ /-- These scripts weren't yet in Perl when I added Unicode 6.0.0 to PCRE --/ /^[\p{Batak}]/8 \x{1bc0} \x{1bff} ** Failers \x{1bf4} /^[\p{Brahmi}]/8 \x{11000} \x{1106f} ** Failers \x{1104e} /^[\p{Mandaic}]/8 \x{840} \x{85e} ** Failers \x{85c} \x{85d} /-- --/ /(\X*)(.)/s8 A\x{300} /^S(\X*)e(\X*)$/8 SteÌreÌo /^\X/8 ÌreÌo /^a\X41z/ aX41z *** Failers aAz /(?<=ab\Cde)X/8 /\X/ a\P a\P\P /\Xa/ aa\P aa\P\P /\X{2}/ aa\P aa\P\P /\X+a/ a\P aa\P aa\P\P /\X+?a/ a\P ab\P aa\P aa\P\P aba\P /-- These Unicode 6.1.0 scripts are not known to Perl. --/ /\p{Chakma}\d/8W \x{11100}\x{1113c} /\p{Takri}\d/8W \x{11680}\x{116c0} /^\X/8 A\P A\P\P A\x{300}\x{301}\P A\x{300}\x{301}\P\P A\x{301}\P A\x{301}\P\P /^\X{2,3}/8 A\P A\P\P AA\P AA\P\P A\x{300}\x{301}\P A\x{300}\x{301}\P\P A\x{300}\x{301}A\x{300}\x{301}\P A\x{300}\x{301}A\x{300}\x{301}\P\P /^\X{2}/8 AA\P AA\P\P A\x{300}\x{301}A\x{300}\x{301}\P A\x{300}\x{301}A\x{300}\x{301}\P\P /^\X+/8 AA\P AA\P\P /^\X+?Z/8 AA\P AA\P\P /-- End of testinput7 --/ pcre-8.31/testdata/testinput80000644000222100022210000024476711767425317013227 00000000000000/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running it. --/ /abc/ abc /ab*c/ abc abbbbc ac /ab+c/ abc abbbbbbc *** Failers ac ab /a*/ a aaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F /(a|abcd|african)/ a abcd african /^abc/ abcdef *** Failers xyzabc xyz\nabc /^abc/m abcdef xyz\nabc *** Failers xyzabc /\Aabc/ abcdef *** Failers xyzabc xyz\nabc /\Aabc/m abcdef *** Failers xyzabc xyz\nabc /\Gabc/ abcdef xyzabc\>3 *** Failers xyzabc xyzabc\>2 /x\dy\Dz/ x9yzz x0y+z *** Failers xyz xxy0z /x\sy\Sz/ x yzz x y+z *** Failers xyz xxyyz /x\wy\Wz/ xxy+z *** Failers xxy0z x+y+z /x.y/ x+y x-y *** Failers x\ny /x.y/s x+y x-y x\ny /(a.b(?s)c.d|x.y)p.q/ a+bc+dp+q a+bc\ndp+q x\nyp+q *** Failers a\nbc\ndp+q a+bc\ndp\nq x\nyp\nq /a\d\z/ ba0 *** Failers ba0\n ba0\ncd /a\d\z/m ba0 *** Failers ba0\n ba0\ncd /a\d\Z/ ba0 ba0\n *** Failers ba0\ncd /a\d\Z/m ba0 ba0\n *** Failers ba0\ncd /a\d$/ ba0 ba0\n *** Failers ba0\ncd /a\d$/m ba0 ba0\n ba0\ncd *** Failers /abc/i abc aBc ABC /[^a]/ abcd /ab?\w/ abz abbz azz /x{0,3}yz/ ayzq axyzq axxyz axxxyzq axxxxyzq *** Failers ax axx /x{3}yz/ axxxyzq axxxxyzq *** Failers ax axx ayzq axyzq axxyz /x{2,3}yz/ axxyz axxxyzq axxxxyzq *** Failers ax axx ayzq axyzq /[^a]+/ bac bcdefax *** Failers aaaaa /[^a]*/ bac bcdefax *** Failers aaaaa /[^a]{3,5}/ xyz awxyza abcdefa abcdefghijk *** Failers axya axa aaaaa /\d*/ 1234b567 xyz /\D*/ a1234b567 xyz /\d+/ ab1234c56 *** Failers xyz /\D+/ ab123c56 *** Failers 789 /\d?A/ 045ABC ABC *** Failers XYZ /\D?A/ ABC BAC 9ABC *** Failers /a+/ aaaa /^.*xyz/ xyz ggggggggxyz /^.+xyz/ abcdxyz axyz *** Failers xyz /^.?xyz/ xyz cxyz /^\d{2,3}X/ 12X 123X *** Failers X 1X 1234X /^[abcd]\d/ a45 b93 c99z d04 *** Failers e45 abcd abcd1234 1234 /^[abcd]*\d/ a45 b93 c99z d04 abcd1234 1234 *** Failers e45 abcd /^[abcd]+\d/ a45 b93 c99z d04 abcd1234 *** Failers 1234 e45 abcd /^a+X/ aX aaX /^[abcd]?\d/ a45 b93 c99z d04 1234 *** Failers abcd1234 e45 /^[abcd]{2,3}\d/ ab45 bcd93 *** Failers 1234 a36 abcd1234 ee45 /^(abc)*\d/ abc45 abcabcabc45 42xyz *** Failers /^(abc)+\d/ abc45 abcabcabc45 *** Failers 42xyz /^(abc)?\d/ abc45 42xyz *** Failers abcabcabc45 /^(abc){2,3}\d/ abcabc45 abcabcabc45 *** Failers abcabcabcabc45 abc45 42xyz /1(abc|xyz)2(?1)3/ 1abc2abc3456 1abc2xyz3456 /^(a*\w|ab)=(a*\w|ab)/ ab=ab /^(a*\w|ab)=(?1)/ ab=ab /^([^()]|\((?1)*\))*$/ abc a(b)c a(b(c))d *** Failers) a(b(c)d /^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)a*)\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 *** Failers aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x <> hij> hij> def> *** Failers 3 *** Failers defabcxyz /^abcdef/ ab\P abcde\P abcdef\P *** Failers abx\P /^a{2,4}\d+z/ a\P aa\P aa2\P aaa\P aaa23\P aaaa12345\P aa0z\P aaaa4444444444444z\P *** Failers az\P aaaaa\P a56\P /^abcdef/ abc\P def\R /(?<=foo)bar/ xyzfo\P foob\P\>2 foobar...\R\P\>4 xyzfo\P foobar\>2 *** Failers xyzfo\P obar\R /(ab*(cd|ef))+X/ adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z cdabbbbbbbb\P\R\B\Z efabbbbbbbbbbbbbbbb\P\R\B\Z bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z /(a|b)/SF>testsavedregex >>aaabxyzpqrrrabbxyyyypqAzz >aaaabxyzpqrrrabbxyyyypqAzz >>>>abcxyzpqrrrabbxyyyypqAzz *** Failers abxyzpqrrabbxyyyypqAzz abxyzpqrrrrabbxyyyypqAzz abxyzpqrrrabxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyypqAzz aaabcxyzpqrrrabbxyyyypqqqqqqqAzz /^(abc){1,2}zz/ abczz abcabczz *** Failers zz abcabcabczz >>abczz /^(b+?|a){1,2}?c/ bc bbc bbbc bac bbac aac abbbbbbbbbbbc bbbbbbbbbbbac *** Failers aaac abbbbbbbbbbbac /^(b+|a){1,2}c/ bc bbc bbbc bac bbac aac abbbbbbbbbbbc bbbbbbbbbbbac *** Failers aaac abbbbbbbbbbbac /^(b+|a){1,2}?bc/ bbc /^(b*|ba){1,2}?bc/ babc bbabc bababc *** Failers bababbc babababc /^(ba|b*){1,2}?bc/ babc bbabc bababc *** Failers bababbc babababc /^\ca\cA\c[\c{\c:/ \x01\x01\e;z /^[ab\]cde]/ athing bthing ]thing cthing dthing ething *** Failers fthing [thing \\thing /^[]cde]/ ]thing cthing dthing ething *** Failers athing fthing /^[^ab\]cde]/ fthing [thing \\thing *** Failers athing bthing ]thing cthing dthing ething /^[^]cde]/ athing fthing *** Failers ]thing cthing dthing ething /^\/ /^ÿ/ ÿ /^[0-9]+$/ 0 1 2 3 4 5 6 7 8 9 10 100 *** Failers abc /^.*nter/ enter inter uponter /^xxx[0-9]+$/ xxx0 xxx1234 *** Failers xxx /^.+[0-9][0-9][0-9]$/ x123 xx123 123456 *** Failers 123 x1234 /^.+?[0-9][0-9][0-9]$/ x123 xx123 123456 *** Failers 123 x1234 /^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ abc!pqr=apquxz.ixr.zzz.ac.uk *** Failers !pqr=apquxz.ixr.zzz.ac.uk abc!=apquxz.ixr.zzz.ac.uk abc!pqr=apquxz:ixr.zzz.ac.uk abc!pqr=apquxz.ixr.zzz.ac.ukk /:/ Well, we need a colon: somewhere *** Fail if we don't /([\da-f:]+)$/i 0abc abc fed E :: 5f03:12C0::932e fed def Any old stuff *** Failers 0zzz gzzz fed\x20 Any old rubbish /^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ .1.2.3 A.12.123.0 *** Failers .1.2.3333 1.2.3 1234.2.3 /^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ 1 IN SOA non-sp1 non-sp2( 1 IN SOA non-sp1 non-sp2 ( *** Failers 1IN SOA non-sp1 non-sp2( /^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ a. Z. 2. ab-c.pq-r. sxk.zzz.ac.uk. x-.y-. *** Failers -abc.peq. /^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ *.a *.b0-a *.c3-b.c *.c-a.b-c *** Failers *.0 *.a- *.a-b.c- *.c-a.0-c /^(?=ab(de))(abd)(e)/ abde /^(?!(ab)de|x)(abd)(f)/ abdf /^(?=(ab(cd)))(ab)/ abcd /^[\da-f](\.[\da-f])*$/i a.b.c.d A.B.C.D a.b.c.1.2.3.C /^\".*\"\s*(;.*)?$/ \"1234\" \"abcd\" ; \"\" ; rhubarb *** Failers \"1234\" : things /^$/ \ *** Failers / ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x ab c *** Failers abc ab cde /(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ ab c *** Failers abc ab cde /^ a\ b[c ]d $/x a bcd a b d *** Failers abcd ab d /^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ abcdefhijklm /^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ abcdefhijklm /^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ a+ Z0+\x08\n\x1d\x12 /^[.^$|()*+?{,}]+/ .^\$(*+)|{?,?} /^a*\w/ z az aaaz a aa aaaa a+ aa+ /^a*?\w/ z az aaaz a aa aaaa a+ aa+ /^a+\w/ az aaaz aa aaaa aa+ /^a+?\w/ az aaaz aa aaaa aa+ /^\d{8}\w{2,}/ 1234567890 12345678ab 12345678__ *** Failers 1234567 /^[aeiou\d]{4,5}$/ uoie 1234 12345 aaaaa *** Failers 123456 /^[aeiou\d]{4,5}?/ uoie 1234 12345 aaaaa 123456 /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ From abcd Mon Sep 01 12:33:02 1997 /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ From abcd Mon Sep 01 12:33:02 1997 From abcd Mon Sep 1 12:33:02 1997 *** Failers From abcd Sep 01 12:33:02 1997 /^12.34/s 12\n34 12\r34 /\w+(?=\t)/ the quick brown\t fox /foo(?!bar)(.*)/ foobar is foolish see? /(?:(?!foo)...|^.{0,2})bar(.*)/ foobar crowbar etc barrel 2barrel A barrel /^(\D*)(?=\d)(?!123)/ abc456 *** Failers abc123 /^1234(?# test newlines inside)/ 1234 /^1234 #comment in extended re /x 1234 /#rhubarb abcd/x abcd /^abcd#rhubarb/x abcd /(?!^)abc/ the abc *** Failers abc /(?=^)abc/ abc *** Failers the abc /^[ab]{1,3}(ab*|b)/ aabbbbb /^[ab]{1,3}?(ab*|b)/ aabbbbb /^[ab]{1,3}?(ab*?|b)/ aabbbbb /^[ab]{1,3}(ab*?|b)/ aabbbbb / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /x Alan Other user\@dom.ain \"A. Other\" (a comment) A. Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) # leading word [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces (?: (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) | " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " ) # "special" comment or quoted string [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" )* < [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # < (?: @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* (?: , [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* )* # additional domains : [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address spec > # > # name and address ) /x Alan Other user\@dom.ain \"A. Other\" (a comment) A. Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay A missing angle a\rb *** Failers a\nb /abc$/ abc abc\n *** Failers abc\ndef /(abc)\123/ abc\x53 /(abc)\223/ abc\x93 /(abc)\323/ abc\xd3 /(abc)\100/ abc\x40 abc\100 /(abc)\1000/ abc\x400 abc\x40\x30 abc\1000 abc\100\x30 abc\100\060 abc\100\60 /abc\81/ abc\081 abc\0\x38\x31 /abc\91/ abc\091 abc\0\x39\x31 /(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ abcdefghijk\12S /ab\idef/ abidef /a{0}bc/ bc /(a|(bc)){0,0}?xyz/ xyz /abc[\10]de/ abc\010de /abc[\1]de/ abc\1de /(abc)[\1]de/ abc\1de /(?s)a.b/ a\nb /^([^a])([^\b])([^c]*)([^d]{3,4})/ baNOTccccd baNOTcccd baNOTccd bacccd *** Failers anything b\bc baccd /[^a]/ Abc /[^a]/i Abc /[^a]+/ AAAaAbc /[^a]+/i AAAaAbc /[^a]+/ bbb\nccc /[^k]$/ abc *** Failers abk /[^k]{2,3}$/ abc kbc kabc *** Failers abk akb akk /^\d{8,}\@.+[^k]$/ 12345678\@a.b.c.d 123456789\@x.y.z *** Failers 12345678\@x.y.uk 1234567\@a.b.c.d /[^a]/ aaaabcd aaAabcd /[^a]/i aaaabcd aaAabcd /[^az]/ aaaabcd aaAabcd /[^az]/i aaaabcd aaAabcd /\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 /P[^*]TAIRE[^*]{1,6}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx /P[^*]TAIRE[^*]{1,}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx /(\.\d\d[1-9]?)\d+/ 1.230003938 1.875000282 1.235 /(\.\d\d((?=0)|\d(?=\d)))/ 1.230003938 1.875000282 *** Failers 1.235 /a(?)b/ ab /\b(foo)\s+(\w+)/i Food is on the foo table /foo(.*)bar/ The food is under the bar in the barn. /foo(.*?)bar/ The food is under the bar in the barn. /(.*)(\d*)/ I have 2 numbers: 53147 /(.*)(\d+)/ I have 2 numbers: 53147 /(.*?)(\d*)/ I have 2 numbers: 53147 /(.*?)(\d+)/ I have 2 numbers: 53147 /(.*)(\d+)$/ I have 2 numbers: 53147 /(.*?)(\d+)$/ I have 2 numbers: 53147 /(.*)\b(\d+)$/ I have 2 numbers: 53147 /(.*\D)(\d+)$/ I have 2 numbers: 53147 /^\D*(?!123)/ ABC123 /^(\D*)(?=\d)(?!123)/ ABC445 *** Failers ABC123 /^[W-]46]/ W46]789 -46]789 *** Failers Wall Zebra 42 [abcd] ]abcd[ /^[W-\]46]/ W46]789 Wall Zebra Xylophone 42 [abcd] ]abcd[ \\backslash *** Failers -46]789 well /\d\d\/\d\d\/\d\d\d\d/ 01/01/2000 /word (?:[a-zA-Z0-9]+ ){0,10}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark /word (?:[a-zA-Z0-9]+ ){0,300}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope /^(a){0,0}/ bcd abc aab /^(a){0,1}/ bcd abc aab /^(a){0,2}/ bcd abc aab /^(a){0,3}/ bcd abc aab aaa /^(a){0,}/ bcd abc aab aaa aaaaaaaa /^(a){1,1}/ bcd abc aab /^(a){1,2}/ bcd abc aab /^(a){1,3}/ bcd abc aab aaa /^(a){1,}/ bcd abc aab aaa aaaaaaaa /.*\.gif/ borfle\nbib.gif\nno /.{0,}\.gif/ borfle\nbib.gif\nno /.*\.gif/m borfle\nbib.gif\nno /.*\.gif/s borfle\nbib.gif\nno /.*\.gif/ms borfle\nbib.gif\nno /.*$/ borfle\nbib.gif\nno /.*$/m borfle\nbib.gif\nno /.*$/s borfle\nbib.gif\nno /.*$/ms borfle\nbib.gif\nno /.*$/ borfle\nbib.gif\nno\n /.*$/m borfle\nbib.gif\nno\n /.*$/s borfle\nbib.gif\nno\n /.*$/ms borfle\nbib.gif\nno\n /(.*X|^B)/ abcde\n1234Xyz BarFoo *** Failers abcde\nBar /(.*X|^B)/m abcde\n1234Xyz BarFoo abcde\nBar /(.*X|^B)/s abcde\n1234Xyz BarFoo *** Failers abcde\nBar /(.*X|^B)/ms abcde\n1234Xyz BarFoo abcde\nBar /(?s)(.*X|^B)/ abcde\n1234Xyz BarFoo *** Failers abcde\nBar /(?s:.*X|^B)/ abcde\n1234Xyz BarFoo *** Failers abcde\nBar /^.*B/ **** Failers abc\nB /(?s)^.*B/ abc\nB /(?m)^.*B/ abc\nB /(?ms)^.*B/ abc\nB /(?ms)^B/ abc\nB /(?s)B$/ B\n /^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ 123456654321 /^\d\d\d\d\d\d\d\d\d\d\d\d/ 123456654321 /^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ 123456654321 /^[abc]{12}/ abcabcabcabc /^[a-c]{12}/ abcabcabcabc /^(a|b|c){12}/ abcabcabcabc /^[abcdefghijklmnopqrstuvwxy0123456789]/ n *** Failers z /abcde{0,0}/ abcd *** Failers abce /ab[cd]{0,0}e/ abe *** Failers abcde /ab(c){0,0}d/ abd *** Failers abcd /a(b*)/ a ab abbbb *** Failers bbbbb /ab\d{0}e/ abe *** Failers ab1e /"([^\\"]+|\\.)*"/ the \"quick\" brown fox \"the \\\"quick\\\" brown fox\" /.*?/g+ abc /\b/g+ abc /\b/+g abc //g abc /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is 43.
Word Processor
(N-1286)
Lega lstaff.comCA - Statewide /a[^a]b/ acb a\nb /a.b/ acb *** Failers a\nb /a[^a]b/s acb a\nb /a.b/s acb a\nb /^(b+?|a){1,2}?c/ bac bbac bbbac bbbbac bbbbbac /^(b+|a){1,2}?c/ bac bbac bbbac bbbbac bbbbbac /(?!\A)x/m x\nb\n a\bx\n /\x0{ab}/ \0{ab} /(A|B)*?CD/ CD /(A|B)*CD/ CD /(?.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ "(?>.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo /(?>(\.\d\d[1-9]?))\d+/ 1.230003938 1.875000282 *** Failers 1.235 /^((?>\w+)|(?>\s+))*$/ now is the time for all good men to come to the aid of the party *** Failers this is not a line with only words and spaces! /(\d+)(\w)/ 12345a 12345+ /((?>\d+))(\w)/ 12345a *** Failers 12345+ /(?>a+)b/ aaab /((?>a+)b)/ aaab /(?>(a+))b/ aaab /(?>b)+/ aaabbbccc /(?>a+|b+|c+)*c/ aaabbbbccccd /(a+|b+|c+)*c/ aaabbbbccccd /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x /\(((?>[^()]+)|\([^()]+\))+\)/ (abc) (abc(def)xyz) *** Failers ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /a(?-i)b/i ab Ab *** Failers aB AB /(a (?x)b c)d e/ a bcd e *** Failers a b cd e abcd e a bcde /(a b(?x)c d (?-x)e f)/ a bcde f *** Failers abcdef /(a(?i)b)c/ abc aBc *** Failers abC aBC Abc ABc ABC AbC /a(?i:b)c/ abc aBc *** Failers ABC abC aBC /a(?i:b)*c/ aBc aBBc *** Failers aBC aBBC /a(?=b(?i)c)\w\wd/ abcd abCd *** Failers aBCd abcD /(?s-i:more.*than).*million/i more than million more than MILLION more \n than Million *** Failers MORE THAN MILLION more \n than \n million /(?:(?s-i)more.*than).*million/i more than million more than MILLION more \n than Million *** Failers MORE THAN MILLION more \n than \n million /(?>a(?i)b+)+c/ abc aBbc aBBc *** Failers Abc abAb abbC /(?=a(?i)b)\w\wc/ abc aBc *** Failers Ab abC aBC /(?<=a(?i)b)(\w\w)c/ abxxc aBxxc *** Failers Abxxc ABxxc abxxC /^(?(?=abc)\w{3}:|\d\d)$/ abc: 12 *** Failers 123 xyz /^(?(?!abc)\d\d|\w{3}:)$/ abc: 12 *** Failers 123 xyz /(?(?<=foo)bar|cat)/ foobar cat fcat focat *** Failers foocat /(?(?a*)*/ a aa aaaa /(abc|)+/ abc abcabc abcabcabc xyz /([a]*)*/ a aaaaa /([ab]*)*/ a b ababab aaaabcde bbbb /([^a]*)*/ b bbbb aaa /([^ab]*)*/ cccc abab /([a]*?)*/ a aaaa /([ab]*?)*/ a b abab baba /([^a]*?)*/ b bbbb aaa /([^ab]*?)*/ c cccc baba /(?>a*)*/ a aaabcde /((?>a*))*/ aaaaa aabbaa /((?>a*?))*/ aaaaa aabbaa /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x 12-sep-98 12-09-98 *** Failers sep-12-98 /(?i:saturday|sunday)/ saturday sunday Saturday Sunday SATURDAY SUNDAY SunDay /(a(?i)bc|BB)x/ abcx aBCx bbx BBx *** Failers abcX aBCX bbX BBX /^([ab](?i)[cd]|[ef])/ ac aC bD elephant Europe frog France *** Failers Africa /^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ ab aBd xy xY zebra Zambesi *** Failers aCD XY /(?<=foo\n)^bar/m foo\nbar *** Failers bar baz\nbar /(?<=(?]&/ <&OUT /(?:(f)(o)(o)|(b)(a)(r))*/ foobar /(?<=a)b/ ab *** Failers cb b /(?a+)ab/ /(?>a+)b/ aaab /([[:]+)/ a:[b]: /([[=]+)/ a=[b]= /([[.]+)/ a.[b]. /((?>a+)b)/ aaab /(?>(a+))b/ aaab /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x /a\Z/ *** Failers aaab a\nb\n /b\Z/ a\nb\n /b\z/ /b\Z/ a\nb /b\z/ a\nb *** Failers /(?>.*)(?<=(abcd|wxyz))/ alphabetabcd endingwxyz *** Failers a rather long string that doesn't end with one of them /word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark /word (?>[a-zA-Z0-9]+ ){0,30}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope /(?<=\d{3}(?!999))foo/ 999foo 123999foo *** Failers 123abcfoo /(?<=(?!...999)\d{3})foo/ 999foo 123999foo *** Failers 123abcfoo /(?<=\d{3}(?!999)...)foo/ 123abcfoo 123456foo *** Failers 123999foo /(?<=\d{3}...)(?Z)+|A)*/ ZABCDEFG /((?>)+|A)*/ ZABCDEFG /a*/g abbab /^[a-\d]/ abcde -things 0digit *** Failers bcdef /^[\d-a]/ abcde -things 0digit *** Failers bcdef /[[:space:]]+/ > \x09\x0a\x0c\x0d\x0b< /[[:blank:]]+/ > \x09\x0a\x0c\x0d\x0b< /[\s]+/ > \x09\x0a\x0c\x0d\x0b< /\s+/ > \x09\x0a\x0c\x0d\x0b< /a b/x ab /(?!\A)x/m a\nxb\n /(?!^)x/m a\nxb\n /abc\Qabc\Eabc/ abcabcabc /abc\Q(*+|\Eabc/ abc(*+|abc / abc\Q abc\Eabc/x abc abcabc *** Failers abcabcabc /abc#comment \Q#not comment literal\E/x abc#not comment\n literal /abc#comment \Q#not comment literal/x abc#not comment\n literal /abc#comment \Q#not comment literal\E #more comment /x abc#not comment\n literal /abc#comment \Q#not comment literal\E #more comment/x abc#not comment\n literal /\Qabc\$xyz\E/ abc\\\$xyz /\Qabc\E\$\Qxyz\E/ abc\$xyz /\Gabc/ abc *** Failers xyzabc /\Gabc./g abc1abc2xyzabc3 /abc./g abc1abc2xyzabc3 /a(?x: b c )d/ XabcdY *** Failers Xa b c d Y /((?x)x y z | a b c)/ XabcY AxyzB /(?i)AB(?-i)C/ XabCY *** Failers XabcY /((?i)AB(?-i)C|D)E/ abCE DE *** Failers abcE abCe dE De /[z\Qa-d]\E]/ z a - d ] *** Failers b /[\z\C]/ z C /\M/ M /(a+)*b/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /(?i)reg(?:ul(?:[aä]|ae)r|ex)/ REGular regulaer Regex regulär /Åæåä[à-ÿÀ-ß]+/ Åæåäà Åæåäÿ ÅæåäÀ Åæåäß /(?<=Z)X./ \x84XAZXB /^(?(2)a|(1)(2))+$/ 123a /(?<=a|bbbb)c/ ac bbbbc /abc/SS>testsavedregex testsavedregex testsavedregex testsavedregex xyz\r\nabc\ xyz\rabc\ xyz\r\nabc\ ** Failers xyz\nabc\ xyz\r\nabc\ xyz\nabc\ xyz\rabc\ xyz\rabc\ /abc$/m xyzabc xyzabc\n xyzabc\npqr xyzabc\r\ xyzabc\rpqr\ xyzabc\r\n\ xyzabc\r\npqr\ ** Failers xyzabc\r xyzabc\rpqr xyzabc\r\n xyzabc\r\npqr /^abc/m xyz\rabcdef xyz\nabcdef\ ** Failers xyz\nabcdef /^abc/m xyz\nabcdef xyz\rabcdef\ ** Failers xyz\rabcdef /^abc/m xyz\r\nabcdef xyz\rabcdef\ ** Failers xyz\rabcdef /.*/ abc\ndef abc\rdef abc\r\ndef \abc\ndef \abc\rdef \abc\r\ndef \abc\ndef \abc\rdef \abc\r\ndef /\w+(.)(.)?def/s abc\ndef abc\rdef abc\r\ndef /^\w+=.*(\\\n.*)*/ abc=xyz\\\npqr /^(a()*)*/ aaaa /^(?:a(?:(?:))*)*/ aaaa /^(a()+)+/ aaaa /^(?:a(?:(?:))+)+/ aaaa /(a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /(?>a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /(?:a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /^a.b/ a\rb a\nb\ ** Failers a\nb a\nb\ a\rb\ a\rb\ /^abc./mgx abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK /abc.$/mgx abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 /^a\Rb/ a\nb a\rb a\r\nb a\x0bb a\x0cb a\x85b ** Failers a\n\rb /^a\R*b/ ab a\nb a\rb a\r\nb a\x0bb a\x0cb a\x85b a\n\rb a\n\r\x85\x0cb /^a\R+b/ a\nb a\rb a\r\nb a\x0bb a\x0cb a\x85b a\n\rb a\n\r\x85\x0cb ** Failers ab /^a\R{1,3}b/ a\nb a\n\rb a\n\r\x85b a\r\n\r\nb a\r\n\r\n\r\nb a\n\r\n\rb a\n\n\r\nb ** Failers a\n\n\n\rb a\r /^a[\R]b/ aRb ** Failers a\nb /.+foo/ afoo ** Failers \r\nfoo \nfoo /.+foo/ afoo \nfoo ** Failers \r\nfoo /.+foo/ afoo ** Failers \nfoo \r\nfoo /.+foo/s afoo \r\nfoo \nfoo /^$/mg abc\r\rxyz abc\n\rxyz ** Failers abc\r\nxyz /^X/m XABC ** Failers XABC\B /(?m)^$/g+ abc\r\n\r\n /(?m)^$|^\r\n/g+ abc\r\n\r\n /(?m)$/g+ abc\r\n\r\n /(?|(abc)|(xyz))/ >abc< >xyz< /(x)(?|(abc)|(xyz))(x)/ xabcx xxyzx /(x)(?|(abc)(pqr)|(xyz))(x)/ xabcpqrx xxyzx /(?|(abc)|(xyz))(?1)/ abcabc xyzabc ** Failers xyzxyz /\H\h\V\v/ X X\x0a X\x09X\x0b ** Failers \xa0 X\x0a /\H*\h+\V?\v{3,4}/ \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a \x09\x20\xa0\x0a\x0b\x0c ** Failers \x09\x20\xa0\x0a\x0b /\H{3,4}/ XY ABCDE XY PQR ST /.\h{3,4}./ XY AB PQRS /\h*X\h?\H+Y\H?Z/ >XNNNYZ > X NYQZ ** Failers >XYZ > X NY Z /\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ >XY\x0aZ\x0aA\x0bNN\x0c >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c /.+A/ \r\nA /\nA/ \r\nA /[\r\n]A/ \r\nA /(\r|\n)A/ \r\nA /a\Rb/I a\rb a\nb a\r\nb ** Failers a\x85b a\x0bb /a\Rb/I a\rb a\nb a\r\nb a\x85b a\x0bb ** Failers a\x85b\ a\x0bb\ /a\R?b/I a\rb a\nb a\r\nb ** Failers a\x85b a\x0bb /a\R?b/I a\rb a\nb a\r\nb a\x85b a\x0bb ** Failers a\x85b\ a\x0bb\ /a\R{2,4}b/I a\r\n\nb a\n\r\rb a\r\n\r\n\r\n\r\nb ** Failers a\x85\85b a\x0b\0bb /a\R{2,4}b/I a\r\rb a\n\n\nb a\r\n\n\r\rb a\x85\85b a\x0b\0bb ** Failers a\r\r\r\r\rb a\x85\85b\ a\x0b\0bb\ /a(?!)|\wbc/ abc /a[]b/ ** Failers ab /a[]+b/ ** Failers ab /a[]*+b/ ** Failers ab /a[^]b/ aXb a\nb ** Failers ab /a[^]+b/ aXb a\nX\nXb ** Failers ab /X$/E X ** Failers X\n /X$/ X X\n /xyz/C xyz abcxyz abcxyz\Y ** Failers abc abc\Y abcxypqr abcxypqr\Y /(*NO_START_OPT)xyz/C abcxyz /(?C)ab/ ab \C-ab /ab/C ab \C-ab /^"((?(?=[a])[^"])|b)*"$/C "ab" \C-"ab" /\d+X|9+Y/ ++++123999\P ++++123999Y\P /Z(*F)/ Z\P ZA\P /Z(?!)/ Z\P ZA\P /dog(sbody)?/ dogs\P dogs\P\P /dog(sbody)??/ dogs\P dogs\P\P /dog|dogsbody/ dogs\P dogs\P\P /dogsbody|dog/ dogs\P dogs\P\P /Z(*F)Q|ZXY/ Z\P ZA\P X\P /\bthe cat\b/ the cat\P the cat\P\P /dog(sbody)?/ dogs\D\P body\D\R /dog(sbody)?/ dogs\D\P\P body\D\R /abc/ abc\P abc\P\P /abc\K123/ xyzabc123pqr /(?<=abc)123/ xyzabc123pqr xyzabc12\P xyzabc12\P\P /\babc\b/ +++abc+++ +++ab\P +++ab\P\P /(?=C)/g+ ABCDECBA /(abc|def|xyz)/I terhjk;abcdaadsfe the quick xyz brown fox \Yterhjk;abcdaadsfe \Ythe quick xyz brown fox ** Failers thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd /(abc|def|xyz)/SI terhjk;abcdaadsfe the quick xyz brown fox \Yterhjk;abcdaadsfe \Ythe quick xyz brown fox ** Failers thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd /abcd*/+ xxxxabcd\P xxxxabcd\P\P dddxxx\R xxxxabcd\P\P xxx\R /abcd*/i xxxxabcd\P xxxxabcd\P\P XXXXABCD\P XXXXABCD\P\P /abc\d*/ xxxxabc1\P xxxxabc1\P\P /abc[de]*/ xxxxabcde\P xxxxabcde\P\P /(?:(?1)|B)(A(*F)|C)/ ABCD CCD ** Failers CAD /^(?:(?1)|B)(A(*F)|C)/ CCD BCD ** Failers ABCD CAD BAD /^(?!a(*SKIP)b)/ ac /^(?=a(*SKIP)b|ac)/ ** Failers ac /^(?=a(*THEN)b|ac)/ ac /^(?=a(*PRUNE)b)/ ab ** Failers ac /^(?(?!a(*SKIP)b))/ ac /(?<=abc)def/ abc\P\P /abc$/ abc abc\P abc\P\P /abc$/m abc abc\n abc\P\P abc\n\P\P abc\P abc\n\P /abc\z/ abc abc\P abc\P\P /abc\Z/ abc abc\P abc\P\P /abc\b/ abc abc\P abc\P\P /abc\B/ abc abc\P abc\P\P /.+/ abc\>0 abc\>1 abc\>2 abc\>3 abc\>4 abc\>-4 /^(?:a)++\w/ aaaab ** Failers aaaa bbb /^(?:aa|(?:a)++\w)/ aaaab aaaa ** Failers bbb /^(?:a)*+\w/ aaaab bbb ** Failers aaaa /^(a)++\w/ aaaab ** Failers aaaa bbb /^(a|)++\w/ aaaab ** Failers aaaa bbb /(?=abc){3}abc/+ abcabcabc ** Failers xyz /(?=abc)+abc/+ abcabcabc ** Failers xyz /(?=abc)++abc/+ abcabcabc ** Failers xyz /(?=abc){0}xyz/ xyz /(?=abc){1}xyz/ ** Failers xyz /(?=(a))?./ ab bc /(?=(a))??./ ab bc /^(?=(a)){0}b(?1)/ backgammon /^(?=(?1))?[az]([abc])d/ abd zcdxx /^(?!a){0}\w+/ aaaaa /(?<=(abc))?xyz/ abcxyz pqrxyz /((?2))((?1))/ abc /(?(R)a+|(?R)b)/ aaaabcde /(?(R)a+|((?R))b)/ aaaabcde /((?(R)a+|(?1)b))/ aaaabcde /((?(R2)a+|(?1)b))/ aaaabcde /(?(R)a*(?1)|((?R))b)/ aaaabcde /(a+)/ \O6aaaa \O8aaaa /ab\Cde/ abXde /(?<=ab\Cde)X/ abZdeX /^\R/ \r\P \r\P\P /^\R{2,3}x/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P \r\rx \r\r\rx /^\R{2,3}?x/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P \r\rx \r\r\rx /^\R?x/ \r\P \r\P\P x \rx /^\R+x/ \r\P \r\P\P \r\n\P \r\n\P\P \rx /^a$/ a\r\P a\r\P\P /^a$/m a\r\P a\r\P\P /^(a$|a\r)/ a\r\P a\r\P\P /^(a$|a\r)/m a\r\P a\r\P\P /./ \r\P \r\P\P /.{2,3}/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /.{2,3}?/ \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /-- Test simple validity check for restarts --/ /abcdef/ abc\R /)(.)|(?R))++)*F>/ text text xxxxx text F> text2 more text. /^(?>.{4})abc|^\w\w.xabcd/ xxxxabcd xx\xa0xabcd /^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ xxxxxxxxabcd xx\xa0xxxxxabcd /-- End of testinput8 --/ pcre-8.31/testdata/testinput90000644000222100022210000002636111762205220013174 00000000000000/-- This set of tests checks UTF-8 support with the DFA matching functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running it. --/ /\x{100}ab/8 \x{100}ab /a\x{100}*b/8 ab a\x{100}b a\x{100}\x{100}b /a\x{100}+b/8 a\x{100}b a\x{100}\x{100}b *** Failers ab /\bX/8 Xoanon +Xoanon \x{300}Xoanon *** Failers YXoanon /\BX/8 YXoanon *** Failers Xoanon +Xoanon \x{300}Xoanon /X\b/8 X+oanon ZX\x{300}oanon FAX *** Failers Xoanon /X\B/8 Xoanon *** Failers X+oanon ZX\x{300}oanon FAX /[^a]/8 abcd a\x{100} /^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 ab99 \x{123}\x{123}45 \x{400}\x{401}\x{402}6 *** Failers d99 \x{123}\x{122}4 \x{400}\x{403}6 \x{400}\x{401}\x{402}\x{402}6 /a.b/8 acb a\x7fb a\x{100}b *** Failers a\nb /a(.{3})b/8 a\x{4000}xyb a\x{4000}\x7fyb a\x{4000}\x{100}yb *** Failers a\x{4000}b ac\ncb /a(.*?)(.)/ a\xc0\x88b /a(.*?)(.)/8 a\x{100}b /a(.*)(.)/ a\xc0\x88b /a(.*)(.)/8 a\x{100}b /a(.)(.)/ a\xc0\x92bcd /a(.)(.)/8 a\x{240}bcd /a(.?)(.)/ a\xc0\x92bcd /a(.?)(.)/8 a\x{240}bcd /a(.??)(.)/ a\xc0\x92bcd /a(.??)(.)/8 a\x{240}bcd /a(.{3})b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b *** Failers a\x{1234}b ac\ncb /a(.{3,})b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b *** Failers a\x{1234}b /a(.{3,}?)b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b *** Failers a\x{1234}b /a(.{3,5})b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b axbxxbcdefghijb axxxxxbcdefghijb *** Failers a\x{1234}b axxxxxxbcdefghijb /a(.{3,5}?)b/8 a\x{1234}xyb a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb a\x{1234}\x{4321}\x{3412}\x{3421}b axbxxbcdefghijb axxxxxbcdefghijb *** Failers a\x{1234}b axxxxxxbcdefghijb /^[a\x{c0}]/8 *** Failers \x{100} /(?<=aXb)cd/8 aXbcd /(?<=a\x{100}b)cd/8 a\x{100}bcd /(?<=a\x{100000}b)cd/8 a\x{100000}bcd /(?:\x{100}){3}b/8 \x{100}\x{100}\x{100}b *** Failers \x{100}\x{100}b /\x{ab}/8 \x{ab} \xc2\xab *** Failers \x00{ab} /(?<=(.))X/8 WXYZ \x{256}XYZ *** Failers XYZ /[^a]+/8g bcd \x{100}aY\x{256}Z /^[^a]{2}/8 \x{100}bc /^[^a]{2,}/8 \x{100}bcAa /^[^a]{2,}?/8 \x{100}bca /[^a]+/8ig bcd \x{100}aY\x{256}Z /^[^a]{2}/8i \x{100}bc /^[^a]{2,}/8i \x{100}bcAa /^[^a]{2,}?/8i \x{100}bca /\x{100}{0,0}/8 abcd /\x{100}?/8 abcd \x{100}\x{100} /\x{100}{0,3}/8 \x{100}\x{100} \x{100}\x{100}\x{100}\x{100} /\x{100}*/8 abce \x{100}\x{100}\x{100}\x{100} /\x{100}{1,1}/8 abcd\x{100}\x{100}\x{100}\x{100} /\x{100}{1,3}/8 abcd\x{100}\x{100}\x{100}\x{100} /\x{100}+/8 abcd\x{100}\x{100}\x{100}\x{100} /\x{100}{3}/8 abcd\x{100}\x{100}\x{100}XX /\x{100}{3,5}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX /\x{100}{3,}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX /(?<=a\x{100}{2}b)X/8 Xyyya\x{100}\x{100}bXzzz /\D*/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /\D*/8 \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /\D/8 1X2 1\x{100}2 />\S/8 > >X Y > >\x{100} Y /\d/8 \x{100}3 /\s/8 \x{100} X /\D+/8 12abcd34 *** Failers 1234 /\D{2,3}/8 12abcd34 12ab34 *** Failers 1234 12a34 /\D{2,3}?/8 12abcd34 12ab34 *** Failers 1234 12a34 /\d+/8 12abcd34 *** Failers /\d{2,3}/8 12abcd34 1234abcd *** Failers 1.4 /\d{2,3}?/8 12abcd34 1234abcd *** Failers 1.4 /\S+/8 12abcd34 *** Failers \ \ /\S{2,3}/8 12abcd34 1234abcd *** Failers \ \ /\S{2,3}?/8 12abcd34 1234abcd *** Failers \ \ />\s+ <34 *** Failers />\s{2,3} \s{2,3}? \xff< /[\xff]/8 >\x{ff}< /[^\xFF]/ XYZ /[^\xff]/8 XYZ \x{123} /^[ac]*b/8 xb /^[ac\x{100}]*b/8 xb /^[^x]*b/8i xb /^[^x]*b/8 xb /^\d*b/8 xb /(|a)/g8 catac a\x{256}a /^\x{85}$/8i \x{85} /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK /abc.$/mgx8 abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 /^a\Rb/8 a\nb a\rb a\r\nb a\x0bb a\x0cb a\x{85}b a\x{2028}b a\x{2029}b ** Failers a\n\rb /^a\R*b/8 ab a\nb a\rb a\r\nb a\x0bb a\x0c\x{2028}\x{2029}b a\x{85}b a\n\rb a\n\r\x{85}\x0cb /^a\R+b/8 a\nb a\rb a\r\nb a\x0bb a\x0c\x{2028}\x{2029}b a\x{85}b a\n\rb a\n\r\x{85}\x0cb ** Failers ab /^a\R{1,3}b/8 a\nb a\n\rb a\n\r\x{85}b a\r\n\r\nb a\r\n\r\n\r\nb a\n\r\n\rb a\n\n\r\nb ** Failers a\n\n\n\rb a\r /\h+\V?\v{3,4}/8 \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a /\V?\v{3,4}/8 \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a /\h+\V?\v{3,4}/8 >\x09\x20\x{a0}X\x0a\x0a\x0a< /\V?\v{3,4}/8 >\x09\x20\x{a0}X\x0a\x0a\x0a< /\H\h\V\v/8 X X\x0a X\x09X\x0b ** Failers \x{a0} X\x0a /\H*\h+\V?\v{3,4}/8 \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a \x09\x20\x{a0}\x0a\x0b\x0c ** Failers \x09\x20\x{a0}\x0a\x0b /\H\h\V\v/8 \x{3001}\x{3000}\x{2030}\x{2028} X\x{180e}X\x{85} ** Failers \x{2009} X\x0a /\H*\h+\V?\v{3,4}/8 \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a \x09\x20\x{202f}\x0a\x0b\x0c ** Failers \x09\x{200a}\x{a0}\x{2028}\x0b /a\Rb/I8 a\rb a\nb a\r\nb ** Failers a\x{85}b a\x0bb /a\Rb/I8 a\rb a\nb a\r\nb a\x{85}b a\x0bb ** Failers a\x{85}b\ a\x0bb\ /a\R?b/I8 a\rb a\nb a\r\nb ** Failers a\x{85}b a\x0bb /a\R?b/I8 a\rb a\nb a\r\nb a\x{85}b a\x0bb ** Failers a\x{85}b\ a\x0bb\ /X/8f A\x{1ec5}ABCXYZ /abcd*/8 xxxxabcd\P xxxxabcd\P\P /abcd*/i8 xxxxabcd\P xxxxabcd\P\P XXXXABCD\P XXXXABCD\P\P /abc\d*/8 xxxxabc1\P xxxxabc1\P\P /abc[de]*/8 xxxxabcde\P xxxxabcde\P\P /\bthe cat\b/8 the cat\P the cat\P\P /ab\Cde/8 abXde /(?<=ab\Cde)X/8 /./8 \r\P \r\P\P /.{2,3}/8 \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /.{2,3}?/8 \r\P \r\P\P \r\r\P \r\r\P\P \r\r\r\P \r\r\r\P\P /[^\x{100}]/8 \x{100}\x{101}X /[^\x{100}]+/8 \x{100}\x{101}X /-- End of testinput9 --/ pcre-8.31/testdata/saved160000644000222100022210000000010611676645220012316 00000000000000>ERCP>Rac}abcrpcre-8.31/testdata/greplist0000644000222100022210000000032310573007200012660 00000000000000This is a file of patterns for testing the -f option. Don't include any blank lines because they will match everything! This is no longer true, so have one. pattern line by itself End of the list of patterns. pcre-8.31/testdata/grepinput0000644000222100022210000011066311612331620013056 00000000000000This is a file of miscellaneous text that is used as test data for checking that the pcregrep command is working correctly. The file must be more than 24K long so that it needs more than a single read() call to process it. New features should be added at the end, because some of the tests involve the output of line numbers, and we don't want these to change. PATTERN at the start of a line. In the middle of a line, PATTERN appears. This pattern is in lower case. Here follows a whole lot of stuff that makes the file over 24K long. ------------------------------------------------------------------------------- The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. ------------------------------------------------------------------------------- aaaaa0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbb cccccccccccccccccccccccccccccccccccccccccc aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa eeeee aaaaa2 ffffffffff This is a line before the binary zero. This line contains a binary zero here >< for testing. This is a line after the binary zero. ABOVE the elephant ABOVE ABOVE theatre AB.VE AB.VE the turtle 010203040506 PUT NEW DATA ABOVE THIS LINE. ============================= Check up on PATTERN near the end. This is the last line of this file. pcre-8.31/testdata/testoutput11-160000644000222100022210000004552411721171641013700 00000000000000/-- These are a few representative patterns whose lengths and offsets are to be shown when the link size is 2. This is just a doublecheck test to ensure the sizes don't go horribly wrong when something is changed. The pattern contents are all themselves checked in other tests. Unicode, including property support, is required for these tests. --/ /((?i)b)/BM Memory allocation (code space): 24 ------------------------------------------------------------------ 0 9 Bra 2 5 CBra 1 5 /i b 7 5 Ket 9 9 Ket 11 End ------------------------------------------------------------------ /(?s)(.*X|^B)/BM Memory allocation (code space): 38 ------------------------------------------------------------------ 0 16 Bra 2 7 CBra 1 5 AllAny* 7 X 9 5 Alt 11 ^ 12 B 14 12 Ket 16 16 Ket 18 End ------------------------------------------------------------------ /(?s:.*X|^B)/BM Memory allocation (code space): 36 ------------------------------------------------------------------ 0 15 Bra 2 6 Bra 4 AllAny* 6 X 8 5 Alt 10 ^ 11 B 13 11 Ket 15 15 Ket 17 End ------------------------------------------------------------------ /^[[:alnum:]]/BM Memory allocation (code space): 46 ------------------------------------------------------------------ 0 20 Bra 2 ^ 3 [0-9A-Za-z] 20 20 Ket 22 End ------------------------------------------------------------------ /#/IxMD Memory allocation (code space): 10 ------------------------------------------------------------------ 0 2 Bra 2 2 Ket 4 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: extended No first char No need char /a#/IxMD Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 a 4 4 Ket 6 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: extended First char = 'a' No need char /x?+/BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 x?+ 4 4 Ket 6 End ------------------------------------------------------------------ /x++/BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 x++ 4 4 Ket 6 End ------------------------------------------------------------------ /x{1,3}+/BM Memory allocation (code space): 28 ------------------------------------------------------------------ 0 11 Bra 2 7 Once 4 x 6 x{0,2} 9 7 Ket 11 11 Ket 13 End ------------------------------------------------------------------ /(x)*+/BM Memory allocation (code space): 26 ------------------------------------------------------------------ 0 10 Bra 2 Braposzero 3 5 CBraPos 1 6 x 8 5 KetRpos 10 10 Ket 12 End ------------------------------------------------------------------ /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM Memory allocation (code space): 142 ------------------------------------------------------------------ 0 68 Bra 2 ^ 3 63 CBra 1 6 5 CBra 2 9 a+ 11 5 Ket 13 21 CBra 3 16 [ab]+? 34 21 Ket 36 21 CBra 4 39 [bc]+ 57 21 Ket 59 5 CBra 5 62 \w* 64 5 Ket 66 63 Ket 68 68 Ket 70 End ------------------------------------------------------------------ |8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM Memory allocation (code space): 1648 ------------------------------------------------------------------ 0 821 Bra 2 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X 820 \b 821 821 Ket 823 End ------------------------------------------------------------------ |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM Memory allocation (code space): 1628 ------------------------------------------------------------------ 0 811 Bra 2 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X 810 \b 811 811 Ket 813 End ------------------------------------------------------------------ /(a(?1)b)/BM Memory allocation (code space): 32 ------------------------------------------------------------------ 0 13 Bra 2 9 CBra 1 5 a 7 2 Recurse 9 b 11 9 Ket 13 13 Ket 15 End ------------------------------------------------------------------ /(a(?1)+b)/BM Memory allocation (code space): 40 ------------------------------------------------------------------ 0 17 Bra 2 13 CBra 1 5 a 7 4 Once 9 2 Recurse 11 4 KetRmax 13 b 15 13 Ket 17 17 Ket 19 End ------------------------------------------------------------------ /a(?Pb|c)d(?Pe)/BM Memory allocation (code space): 80 ------------------------------------------------------------------ 0 24 Bra 2 a 4 5 CBra 1 7 b 9 4 Alt 11 c 13 9 Ket 15 d 17 5 CBra 2 20 e 22 5 Ket 24 24 Ket 26 End ------------------------------------------------------------------ /(?:a(?Pc(?Pd)))(?Pa)/BM Memory allocation (code space): 73 ------------------------------------------------------------------ 0 29 Bra 2 18 Bra 4 a 6 12 CBra 1 9 c 11 5 CBra 2 14 d 16 5 Ket 18 12 Ket 20 18 Ket 22 5 CBra 3 25 a 27 5 Ket 29 29 Ket 31 End ------------------------------------------------------------------ /(?Pa)...(?P=a)bbb(?P>a)d/BM Memory allocation (code space): 57 ------------------------------------------------------------------ 0 24 Bra 2 5 CBra 1 5 a 7 5 Ket 9 Any 10 Any 11 Any 12 \1 14 bbb 20 2 Recurse 22 d 24 24 Ket 26 End ------------------------------------------------------------------ /abc(?C255)de(?C)f/BM Memory allocation (code space): 50 ------------------------------------------------------------------ 0 22 Bra 2 abc 8 Callout 255 10 1 12 de 16 Callout 0 16 1 20 f 22 22 Ket 24 End ------------------------------------------------------------------ /abcde/CBM Memory allocation (code space): 78 ------------------------------------------------------------------ 0 36 Bra 2 Callout 255 0 1 6 a 8 Callout 255 1 1 12 b 14 Callout 255 2 1 18 c 20 Callout 255 3 1 24 d 26 Callout 255 4 1 30 e 32 Callout 255 5 0 36 36 Ket 38 End ------------------------------------------------------------------ /\x{100}/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \x{100} 4 4 Ket 6 End ------------------------------------------------------------------ /\x{1000}/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \x{1000} 4 4 Ket 6 End ------------------------------------------------------------------ /\x{10000}/8BM Memory allocation (code space): 16 ------------------------------------------------------------------ 0 5 Bra 2 \x{10000} 5 5 Ket 7 End ------------------------------------------------------------------ /\x{100000}/8BM Memory allocation (code space): 16 ------------------------------------------------------------------ 0 5 Bra 2 \x{100000} 5 5 Ket 7 End ------------------------------------------------------------------ /\x{10ffff}/8BM Memory allocation (code space): 16 ------------------------------------------------------------------ 0 5 Bra 2 \x{10ffff} 5 5 Ket 7 End ------------------------------------------------------------------ /\x{110000}/8BM Failed: character value in \x{...} sequence is too large at offset 9 /[\x{ff}]/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \xff 4 4 Ket 6 End ------------------------------------------------------------------ /[\x{100}]/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \x{100} 4 4 Ket 6 End ------------------------------------------------------------------ /\x80/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \x80 4 4 Ket 6 End ------------------------------------------------------------------ /\xff/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \xff 4 4 Ket 6 End ------------------------------------------------------------------ /\x{0041}\x{2262}\x{0391}\x{002e}/D8M Memory allocation (code space): 26 ------------------------------------------------------------------ 0 10 Bra 2 A\x{2262}\x{391}. 10 10 Ket 12 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'A' Need char = '.' /\x{D55c}\x{ad6d}\x{C5B4}/D8M Memory allocation (code space): 22 ------------------------------------------------------------------ 0 8 Bra 2 \x{d55c}\x{ad6d}\x{c5b4} 8 8 Ket 10 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{d55c} Need char = \x{c5b4} /\x{65e5}\x{672c}\x{8a9e}/D8M Memory allocation (code space): 22 ------------------------------------------------------------------ 0 8 Bra 2 \x{65e5}\x{672c}\x{8a9e} 8 8 Ket 10 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{65e5} Need char = \x{8a9e} /[\x{100}]/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \x{100} 4 4 Ket 6 End ------------------------------------------------------------------ /[Z\x{100}]/8BM Memory allocation (code space): 54 ------------------------------------------------------------------ 0 24 Bra 2 [Z\x{100}] 24 24 Ket 26 End ------------------------------------------------------------------ /^[\x{100}\E-\Q\E\x{150}]/B8M Memory allocation (code space): 26 ------------------------------------------------------------------ 0 10 Bra 2 ^ 3 [\x{100}-\x{150}] 10 10 Ket 12 End ------------------------------------------------------------------ /^[\QÄ€\E-\QÅ\E]/B8M Memory allocation (code space): 26 ------------------------------------------------------------------ 0 10 Bra 2 ^ 3 [\x{100}-\x{150}] 10 10 Ket 12 End ------------------------------------------------------------------ /^[\QÄ€\E-\QÅ\E/B8M Failed: missing terminating ] for character class at offset 13 /[\p{L}]/BM Memory allocation (code space): 24 ------------------------------------------------------------------ 0 9 Bra 2 [\p{L}] 9 9 Ket 11 End ------------------------------------------------------------------ /[\p{^L}]/BM Memory allocation (code space): 24 ------------------------------------------------------------------ 0 9 Bra 2 [\P{L}] 9 9 Ket 11 End ------------------------------------------------------------------ /[\P{L}]/BM Memory allocation (code space): 24 ------------------------------------------------------------------ 0 9 Bra 2 [\P{L}] 9 9 Ket 11 End ------------------------------------------------------------------ /[\P{^L}]/BM Memory allocation (code space): 24 ------------------------------------------------------------------ 0 9 Bra 2 [\p{L}] 9 9 Ket 11 End ------------------------------------------------------------------ /[abc\p{L}\x{0660}]/8BM Memory allocation (code space): 60 ------------------------------------------------------------------ 0 27 Bra 2 [a-c\p{L}\x{660}] 27 27 Ket 29 End ------------------------------------------------------------------ /[\p{Nd}]/8BM Memory allocation (code space): 24 ------------------------------------------------------------------ 0 9 Bra 2 [\p{Nd}] 9 9 Ket 11 End ------------------------------------------------------------------ /[\p{Nd}+-]+/8BM Memory allocation (code space): 58 ------------------------------------------------------------------ 0 26 Bra 2 [+\-\p{Nd}]+ 26 26 Ket 28 End ------------------------------------------------------------------ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM Memory allocation (code space): 32 ------------------------------------------------------------------ 0 13 Bra 2 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} 13 13 Ket 15 End ------------------------------------------------------------------ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM Memory allocation (code space): 32 ------------------------------------------------------------------ 0 13 Bra 2 A\x{391}\x{10427}\x{ff3a}\x{1fb0} 13 13 Ket 15 End ------------------------------------------------------------------ /[\x{105}-\x{109}]/8iBM Memory allocation (code space): 24 ------------------------------------------------------------------ 0 9 Bra 2 [\x{104}-\x{109}] 9 9 Ket 11 End ------------------------------------------------------------------ /( ( (?(1)0|) )* )/xBM Memory allocation (code space): 52 ------------------------------------------------------------------ 0 23 Bra 2 19 CBra 1 5 Brazero 6 13 SCBra 2 9 6 Cond 11 1 Cond ref 13 0 15 2 Alt 17 8 Ket 19 13 KetRmax 21 19 Ket 23 23 Ket 25 End ------------------------------------------------------------------ /( (?(1)0|)* )/xBM Memory allocation (code space): 42 ------------------------------------------------------------------ 0 18 Bra 2 14 CBra 1 5 Brazero 6 6 SCond 8 1 Cond ref 10 0 12 2 Alt 14 8 KetRmax 16 14 Ket 18 18 Ket 20 End ------------------------------------------------------------------ /[a]/BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 a 4 4 Ket 6 End ------------------------------------------------------------------ /[a]/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 a 4 4 Ket 6 End ------------------------------------------------------------------ /[\xaa]/BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \xaa 4 4 Ket 6 End ------------------------------------------------------------------ /[\xaa]/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 \xaa 4 4 Ket 6 End ------------------------------------------------------------------ /[^a]/BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 [^a] 4 4 Ket 6 End ------------------------------------------------------------------ /[^a]/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 [^a] 4 4 Ket 6 End ------------------------------------------------------------------ /[^\xaa]/BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 [^\xaa] 4 4 Ket 6 End ------------------------------------------------------------------ /[^\xaa]/8BM Memory allocation (code space): 14 ------------------------------------------------------------------ 0 4 Bra 2 [^\xaa] 4 4 Ket 6 End ------------------------------------------------------------------ /[^\d]/8WB ------------------------------------------------------------------ 0 9 Bra 2 [^\p{Nd}] 9 9 Ket 11 End ------------------------------------------------------------------ /[[:^alpha:][:^cntrl:]]+/8WB ------------------------------------------------------------------ 0 26 Bra 2 [ -~\x80-\xff\P{L}]+ 26 26 Ket 28 End ------------------------------------------------------------------ /[[:^cntrl:][:^alpha:]]+/8WB ------------------------------------------------------------------ 0 26 Bra 2 [ -~\x80-\xff\P{L}]+ 26 26 Ket 28 End ------------------------------------------------------------------ /[[:alpha:]]+/8WB ------------------------------------------------------------------ 0 10 Bra 2 [\p{L}]+ 10 10 Ket 12 End ------------------------------------------------------------------ /[[:^alpha:]\S]+/8WB ------------------------------------------------------------------ 0 13 Bra 2 [\P{L}\P{Xsp}]+ 13 13 Ket 15 End ------------------------------------------------------------------ /abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B ------------------------------------------------------------------ 0 60 Bra 2 abc 8 5 CBra 1 11 d 13 4 Alt 15 e 17 9 Ket 19 *THEN 20 x 22 12 CBra 2 25 123 31 *THEN 32 4 34 24 Alt 36 567 42 5 CBra 3 45 b 47 4 Alt 49 q 51 9 Ket 53 *THEN 54 xx 58 36 Ket 60 60 Ket 62 End ------------------------------------------------------------------ /-- End of testinput11 --/ pcre-8.31/testdata/greppatN40000644000222100022210000000001011677120430012673 00000000000000xxx jklpcre-8.31/testdata/grepbinary0000644000222100022210000000005511724715402013204 00000000000000The quick brown fx jumps over the lazy dog. pcre-8.31/testdata/testoutput100000644000222100022210000011163411762205311013444 00000000000000/-- This set of tests check Unicode property support with the DFA matching functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running it. --/ /\pL\P{Nd}/8 AB 0: AB *** Failers 0: Fa A0 No match 00 No match /\X./8 AB 0: AB A\x{300}BC 0: A\x{300}B A\x{300}\x{301}\x{302}BC 0: A\x{300}\x{301}\x{302}B *** Failers 0: ** \x{300} No match /\X\X/8 ABC 0: AB A\x{300}B\x{300}\x{301}C 0: A\x{300}B\x{300}\x{301} A\x{300}\x{301}\x{302}BC 0: A\x{300}\x{301}\x{302}B *** Failers 0: ** \x{300} No match /^\pL+/8 abcd 0: abcd 1: abc 2: ab 3: a a 0: a *** Failers No match /^\PL+/8 1234 0: 1234 1: 123 2: 12 3: 1 = 0: = *** Failers 0: *** 1: *** 2: ** 3: * abcd No match /^\X+/8 abcdA\x{300}\x{301}\x{302} 0: abcdA\x{300}\x{301}\x{302} 1: abcd 2: abc 3: ab 4: a A\x{300}\x{301}\x{302} 0: A\x{300}\x{301}\x{302} A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} 1: A\x{300}\x{301}\x{302} a 0: a *** Failers 0: *** Failers 1: *** Failer 2: *** Faile 3: *** Fail 4: *** Fai 5: *** Fa 6: *** F 7: *** 8: *** 9: ** 10: * \x{300}\x{301}\x{302} No match /\X?abc/8 abc 0: abc A\x{300}abc 0: A\x{300}abc A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz 0: A\x{300}abc \x{300}abc 0: abc *** Failers No match /^\X?abc/8 abc 0: abc A\x{300}abc 0: A\x{300}abc *** Failers No match A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz No match \x{300}abc No match /\X*abc/8 abc 0: abc A\x{300}abc 0: A\x{300}abc A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc \x{300}abc 0: abc *** Failers No match /^\X*abc/8 abc 0: abc A\x{300}abc 0: A\x{300}abc A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc *** Failers No match \x{300}abc No match /^\pL?=./8 A=b 0: A=b =c 0: =c *** Failers No match 1=2 No match AAAA=b No match /^\pL*=./8 AAAA=b 0: AAAA=b =c 0: =c *** Failers No match 1=2 No match /^\X{2,3}X/8 A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X *** Failers No match X No match A\x{300}\x{301}\x{302}X No match A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X No match /^\pC\pL\pM\pN\pP\pS\pZ\p{Xsp}/8 >\x{1680}\x{2028}\x{0b} 0: >\x{1680} ** Failers No match \x{0b} No match /^>\p{Xsp}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 3: > \x{09}\x{0a}\x{0c}\x{0d} 4: > \x{09}\x{0a}\x{0c} 5: > \x{09}\x{0a} 6: > \x{09} 7: > /^>\p{Xsp}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 3: > \x{09}\x{0a}\x{0c}\x{0d} 4: > \x{09}\x{0a}\x{0c} 5: > \x{09}\x{0a} 6: > \x{09} 7: > 8: > /^>\p{Xsp}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 3: > \x{09}\x{0a}\x{0c}\x{0d} 4: > \x{09}\x{0a}\x{0c} 5: > \x{09}\x{0a} 6: > \x{09} /^>[\p{Xsp}]/8 >\x{2028}\x{0b} 0: >\x{2028} /^>[\p{Xsp}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 3: > \x{09}\x{0a}\x{0c}\x{0d} 4: > \x{09}\x{0a}\x{0c} 5: > \x{09}\x{0a} 6: > \x{09} 7: > /^>\p{Xps}/8 >\x{1680}\x{2028}\x{0b} 0: >\x{1680} >\x{a0} 0: >\x{a0} ** Failers No match \x{0b} No match /^>\p{Xps}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 4: > \x{09}\x{0a}\x{0c}\x{0d} 5: > \x{09}\x{0a}\x{0c} 6: > \x{09}\x{0a} 7: > \x{09} 8: > /^>\p{Xps}+?/8 >\x{1680}\x{2028}\x{0b} 0: >\x{1680}\x{2028}\x{0b} 1: >\x{1680}\x{2028} 2: >\x{1680} /^>\p{Xps}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 4: > \x{09}\x{0a}\x{0c}\x{0d} 5: > \x{09}\x{0a}\x{0c} 6: > \x{09}\x{0a} 7: > \x{09} 8: > 9: > /^>\p{Xps}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 4: > \x{09}\x{0a}\x{0c}\x{0d} 5: > \x{09}\x{0a}\x{0c} 6: > \x{09}\x{0a} 7: > \x{09} /^>\p{Xps}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 4: > \x{09}\x{0a}\x{0c}\x{0d} 5: > \x{09}\x{0a}\x{0c} 6: > \x{09}\x{0a} 7: > \x{09} /^>[\p{Xps}]/8 >\x{2028}\x{0b} 0: >\x{2028} /^>[\p{Xps}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} 4: > \x{09}\x{0a}\x{0c}\x{0d} 5: > \x{09}\x{0a}\x{0c} 6: > \x{09}\x{0a} 7: > \x{09} 8: > /^\p{Xwd}/8 ABCD 0: A 1234 0: 1 \x{6ca} 0: \x{6ca} \x{a6c} 0: \x{a6c} \x{10a7} 0: \x{10a7} _ABC 0: _ ** Failers No match [] No match /^\p{Xwd}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} 2: ABCD1234\x{6ca}\x{a6c} 3: ABCD1234\x{6ca} 4: ABCD1234 5: ABCD123 6: ABCD12 7: ABCD1 8: ABCD 9: ABC 10: AB 11: A /^\p{Xwd}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} 2: ABCD1234\x{6ca}\x{a6c} 3: ABCD1234\x{6ca} 4: ABCD1234 5: ABCD123 6: ABCD12 7: ABCD1 8: ABCD 9: ABC 10: AB 11: A 12: /^\p{Xwd}{2,9}/8 A_12\x{6ca}\x{a6c}\x{10a7} 0: A_12\x{6ca}\x{a6c}\x{10a7} 1: A_12\x{6ca}\x{a6c} 2: A_12\x{6ca} 3: A_12 4: A_1 5: A_ /^[\p{Xwd}]/8 ABCD1234_ 0: A 1234abcd_ 0: 1 \x{6ca} 0: \x{6ca} \x{a6c} 0: \x{a6c} \x{10a7} 0: \x{10a7} _ABC 0: _ ** Failers No match [] No match /^[\p{Xwd}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} 2: ABCD1234\x{6ca}\x{a6c} 3: ABCD1234\x{6ca} 4: ABCD1234 5: ABCD123 6: ABCD12 7: ABCD1 8: ABCD 9: ABC 10: AB 11: A /-- Unicode properties for \b abd \B --/ /\b...\B/8W abc_ 0: abc \x{37e}abc\x{376} 0: abc \x{37e}\x{376}\x{371}\x{393}\x{394} 0: \x{376}\x{371}\x{393} !\x{c0}++\x{c1}\x{c2} 0: ++\x{c1} !\x{c0}+++++ 0: \x{c0}++ /-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ /\b...\B/8 abc_ 0: abc ** Failers 0: Fai \x{37e}abc\x{376} No match \x{37e}\x{376}\x{371}\x{393}\x{394} No match !\x{c0}++\x{c1}\x{c2} No match !\x{c0}+++++ No match /-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ /\b...\B/W abc_ 0: abc !\x{c0}++\x{c1}\x{c2} 0: ++\xc1 !\x{c0}+++++ 0: \xc0++ /-- Caseless single negated characters > 127 need UCP support --/ /[^\x{100}]/8i \x{100}\x{101}X 0: X /[^\x{100}]+/8i \x{100}\x{101}XX 0: XX 1: X /^\X/8 A\P 0: A A\P\P Partial match: A A\x{300}\x{301}\P 0: A\x{300}\x{301} A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301} A\x{301}\P 0: A\x{301} A\x{301}\P\P Partial match: A\x{301} /^\X{2,3}/8 A\P Partial match: A A\P\P Partial match: A AA\P 0: AA AA\P\P Partial match: AA A\x{300}\x{301}\P Partial match: A\x{300}\x{301} A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301} A\x{300}\x{301}A\x{300}\x{301}\P 0: A\x{300}\x{301}A\x{300}\x{301} A\x{300}\x{301}A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301}A\x{300}\x{301} /^\X{2}/8 AA\P 0: AA AA\P\P Partial match: AA A\x{300}\x{301}A\x{300}\x{301}\P 0: A\x{300}\x{301}A\x{300}\x{301} A\x{300}\x{301}A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301}A\x{300}\x{301} /^\X+/8 AA\P 0: AA 1: A AA\P\P Partial match: AA /^\X+?Z/8 AA\P Partial match: AA AA\P\P Partial match: AA /-- End of testinput10 --/ pcre-8.31/testdata/testoutput120000644000222100022210000000450711741324730013452 00000000000000/-- This test is run only when JIT support is available. It checks for a successful and an unsuccessful JIT compile and save and restore behaviour, and a couple of things that are different with JIT. --/ /abc/S+I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Subject length lower bound = 3 No set of starting bytes JIT study was successful /ab(*THEN)/S+I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' Subject length lower bound = 2 No set of starting bytes JIT study was not successful /abc/S+I>testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Subject length lower bound = 3 No set of starting bytes JIT study was successful Compiled pattern written to testsavedregex Study data written to testsavedregex b)c/PN abc Matched with REG_NOSUB /a?|b?/P abc 0: a ** Failers 0: ddd\N No match: POSIX code 17: match failed /\w+A/P CDAAAAB 0: CDAAAA /\w+A/PU CDAAAAB 0: CDA /\Biss\B/I+P Mississippi 0: iss 0+ issippi /abc/\P Failed: POSIX code 9: bad escape sequence at offset 4 /-- End of POSIX tests --/ /a\Cb/ aXb 0: aXb a\nb 0: a\x0ab ** Failers (too big char) No match A\x{123}B ** Character \x{123} is greater than 255 and UTF-8 mode is not enabled. ** Truncation will probably give the wrong result. No match /\x{100}/I Failed: character value in \x{...} sequence is too large at offset 6 / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /xSI Capturing subpattern count = 0 Contains explicit CR or LF match Options: extended No first char No need char Subject length lower bound = 3 Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f /-- Although this saved pattern was compiled with link-size=2, it does no harm to run this test with other link sizes because it is going to generated a "compiled in wrong mode" error as soon as it is loaded, so the link size does not matter. --/ \x09< 0: \x09 /[\h]+/BZ ------------------------------------------------------------------ Bra [\x09 \xa0]+ Ket End ------------------------------------------------------------------ >\x09\x20\xa0< 0: \x09 \xa0 /[\v]/BZ ------------------------------------------------------------------ Bra [\x0a-\x0d\x85] Ket End ------------------------------------------------------------------ /[\H]/BZ ------------------------------------------------------------------ Bra [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff] Ket End ------------------------------------------------------------------ /[^\h]/BZ ------------------------------------------------------------------ Bra [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff] (neg) Ket End ------------------------------------------------------------------ /[\V]/BZ ------------------------------------------------------------------ Bra [\x00-\x09\x0e-\x84\x86-\xff] Ket End ------------------------------------------------------------------ /[\x0a\V]/BZ ------------------------------------------------------------------ Bra [\x00-\x0a\x0e-\x84\x86-\xff] Ket End ------------------------------------------------------------------ /\777/I Failed: octal value is greater than \377 in 8-bit non-UTF-8 mode at offset 3 /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K Failed: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) at offset 259 /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K XX 0: XX MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE /\u0100/ Failed: character value in \u.... sequence is too large at offset 5 /[\u0100-\u0200]/ Failed: character value in \u.... sequence is too large at offset 6 /-- End of testinput14 --/ pcre-8.31/testdata/testoutput150000644000222100022210000005601111767405226013462 00000000000000/-- This set of tests is for UTF-8 support, and is relevant only to the 8-bit library. --/ /X(\C{3})/8 X\x{1234} 0: X\x{1234} 1: \x{1234} /X(\C{4})/8 X\x{1234}YZ 0: X\x{1234}Y 1: \x{1234}Y /X\C*/8 XYZabcdce 0: XYZabcdce /X\C*?/8 XYZabcde 0: X /X\C{3,5}/8 Xabcdefg 0: Xabcde X\x{1234} 0: X\x{1234} X\x{1234}YZ 0: X\x{1234}YZ X\x{1234}\x{512} 0: X\x{1234}\x{512} X\x{1234}\x{512}YZ 0: X\x{1234}\x{512} /X\C{3,5}?/8 Xabcdefg 0: Xabc X\x{1234} 0: X\x{1234} X\x{1234}YZ 0: X\x{1234} X\x{1234}\x{512} 0: X\x{1234} /a\Cb/8 aXb 0: aXb a\nb 0: a\x{0a}b /a\C\Cb/8 a\x{100}b 0: a\x{100}b /ab\Cde/8 abXde 0: abXde /a\C\Cb/8 a\x{100}b 0: a\x{100}b ** Failers No match a\x{12257}b No match /[Ã]/8 Failed: invalid UTF-8 string at offset 1 /Ã/8 Failed: invalid UTF-8 string at offset 0 /ÃÃÃxxx/8 Failed: invalid UTF-8 string at offset 0 /ÃÃÃxxx/8?DZSS ------------------------------------------------------------------ Bra \X{c0}\X{c0}\X{c0}xxx Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf no_utf_check First char = \x{c3} Need char = 'x' /abc/8 Ã] Error -10 (bad UTF-8 string) offset=0 reason=6 à Error -10 (bad UTF-8 string) offset=0 reason=1 ÃÃà Error -10 (bad UTF-8 string) offset=0 reason=6 ÃÃÃ\? No match \xe1\x88 Error -10 (bad UTF-8 string) offset=0 reason=1 \P\xe1\x88 Error -10 (bad UTF-8 string) offset=0 reason=1 \P\P\xe1\x88 Error -25 (short UTF-8 string) offset=0 reason=1 XX\xea Error -10 (bad UTF-8 string) offset=2 reason=2 \O0XX\xea Error -10 (bad UTF-8 string) \O1XX\xea Error -10 (bad UTF-8 string) \O2XX\xea Error -10 (bad UTF-8 string) offset=2 reason=2 XX\xf1 Error -10 (bad UTF-8 string) offset=2 reason=3 XX\xf8 Error -10 (bad UTF-8 string) offset=2 reason=4 XX\xfc Error -10 (bad UTF-8 string) offset=2 reason=5 ZZ\xea\xaf\x20YY Error -10 (bad UTF-8 string) offset=2 reason=7 ZZ\xfd\xbf\xbf\x2f\xbf\xbfYY Error -10 (bad UTF-8 string) offset=2 reason=8 ZZ\xfd\xbf\xbf\xbf\x2f\xbfYY Error -10 (bad UTF-8 string) offset=2 reason=9 ZZ\xfd\xbf\xbf\xbf\xbf\x2fYY Error -10 (bad UTF-8 string) offset=2 reason=10 ZZ\xffYY Error -10 (bad UTF-8 string) offset=2 reason=21 ZZ\xfeYY Error -10 (bad UTF-8 string) offset=2 reason=21 /anything/8 \xc0\x80 Error -10 (bad UTF-8 string) offset=0 reason=15 \xc1\x8f Error -10 (bad UTF-8 string) offset=0 reason=15 \xe0\x9f\x80 Error -10 (bad UTF-8 string) offset=0 reason=16 \xf0\x8f\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=17 \xf8\x87\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=18 \xfc\x83\x80\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=19 \xfe\x80\x80\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=21 \xff\x80\x80\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=21 \xc3\x8f No match \xe0\xaf\x80 No match \xe1\x80\x80 No match \xf0\x9f\x80\x80 No match \xf1\x8f\x80\x80 No match \xf8\x88\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=11 \xf9\x87\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=11 \xfc\x84\x80\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=12 \xfd\x83\x80\x80\x80\x80 Error -10 (bad UTF-8 string) offset=0 reason=12 \?\xf8\x88\x80\x80\x80 No match \?\xf9\x87\x80\x80\x80 No match \?\xfc\x84\x80\x80\x80\x80 No match \?\xfd\x83\x80\x80\x80\x80 No match /\x{100}/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = \x{80} /\x{1000}/8DZ ------------------------------------------------------------------ Bra \x{1000} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{e1} Need char = \x{80} /\x{10000}/8DZ ------------------------------------------------------------------ Bra \x{10000} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{f0} Need char = \x{80} /\x{100000}/8DZ ------------------------------------------------------------------ Bra \x{100000} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{f4} Need char = \x{80} /\x{10ffff}/8DZ ------------------------------------------------------------------ Bra \x{10ffff} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{f4} Need char = \x{bf} /[\x{ff}]/8DZ ------------------------------------------------------------------ Bra \x{ff} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c3} Need char = \x{bf} /[\x{100}]/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = \x{80} /\x80/8DZ ------------------------------------------------------------------ Bra \x{80} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c2} Need char = \x{80} /\xff/8DZ ------------------------------------------------------------------ Bra \x{ff} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c3} Need char = \x{bf} /\x{D55c}\x{ad6d}\x{C5B4}/DZ8 ------------------------------------------------------------------ Bra \x{d55c}\x{ad6d}\x{c5b4} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{ed} Need char = \x{b4} \x{D55c}\x{ad6d}\x{C5B4} 0: \x{d55c}\x{ad6d}\x{c5b4} /\x{65e5}\x{672c}\x{8a9e}/DZ8 ------------------------------------------------------------------ Bra \x{65e5}\x{672c}\x{8a9e} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{e6} Need char = \x{9e} \x{65e5}\x{672c}\x{8a9e} 0: \x{65e5}\x{672c}\x{8a9e} /\x{80}/DZ8 ------------------------------------------------------------------ Bra \x{80} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c2} Need char = \x{80} /\x{084}/DZ8 ------------------------------------------------------------------ Bra \x{84} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c2} Need char = \x{84} /\x{104}/DZ8 ------------------------------------------------------------------ Bra \x{104} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = \x{84} /\x{861}/DZ8 ------------------------------------------------------------------ Bra \x{861} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{e0} Need char = \x{a1} /\x{212ab}/DZ8 ------------------------------------------------------------------ Bra \x{212ab} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{f0} Need char = \x{ab} /-- This one is here not because it's different to Perl, but because the way the captured single-byte is displayed. (In Perl it becomes a character, and you can't tell the difference.) --/ /X(\C)(.*)/8 X\x{1234} 0: X\x{1234} 1: \x{e1} 2: \x{88}\x{b4} X\nabc 0: X\x{0a}abc 1: \x{0a} 2: abc /-- This one is here because Perl gives out a grumbly error message (quite correctly, but that messes up comparisons). --/ /a\Cb/8 *** Failers No match a\x{100}b No match /[^ab\xC0-\xF0]/8SDZ ------------------------------------------------------------------ Bra [\x00-`c-\xbf\xf1-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff \x{f1} 0: \x{f1} \x{bf} 0: \x{bf} \x{100} 0: \x{100} \x{1000} 0: \x{1000} *** Failers 0: * \x{c0} No match \x{f0} No match /Ä€{3,4}/8SDZ ------------------------------------------------------------------ Bra \x{100}{3} \x{100}? Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = \x{80} Subject length lower bound = 3 No set of starting bytes \x{100}\x{100}\x{100}\x{100\x{100} 0: \x{100}\x{100}\x{100} /(\x{100}+|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100}+ Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: x \xc4 /(\x{100}*a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100}*+ a Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: a x \xc4 /(\x{100}{0,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100}{0,2} a Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: a x \xc4 /(\x{100}{1,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100} \x{100}{0,1} a Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: x \xc4 /\x{100}/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = \x{80} /a\x{100}\x{101}*/8DZ ------------------------------------------------------------------ Bra a\x{100} \x{101}* Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'a' Need char = \x{80} /a\x{100}\x{101}+/8DZ ------------------------------------------------------------------ Bra a\x{100} \x{101}+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'a' Need char = \x{81} /[^\x{c4}]/DZ ------------------------------------------------------------------ Bra [^\xc4] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[\x{100}]/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = \x{80} \x{100} 0: \x{100} Z\x{100} 0: \x{100} \x{100}Z 0: \x{100} *** Failers No match /[\xff]/DZ8 ------------------------------------------------------------------ Bra \x{ff} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c3} Need char = \x{bf} >\x{ff}< 0: \x{ff} /[^\xff]/8DZ ------------------------------------------------------------------ Bra [^\x{ff}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /\x{100}abc(xyz(?1))/8DZ ------------------------------------------------------------------ Bra \x{100}abc CBra 1 xyz Recurse Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf First char = \x{c4} Need char = 'z' /a\x{1234}b/P8 a\x{1234}b 0: a\x{1234}b /\777/8I Capturing subpattern count = 0 Options: utf First char = \x{c7} Need char = \x{bf} \x{1ff} 0: \x{1ff} \777 0: \x{1ff} /\x{100}+\x{200}/8DZ ------------------------------------------------------------------ Bra \x{100}++ \x{200} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = \x{80} /\x{100}+X/8DZ ------------------------------------------------------------------ Bra \x{100}++ X Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c4} Need char = 'X' /^[\QÄ€\E-\QÅ\E/BZ8 Failed: missing terminating ] for character class at offset 15 /-- This tests the stricter UTF-8 check according to RFC 3629. --/ /X/8 \x{0}\x{d7ff}\x{e000}\x{10ffff} No match \x{d800} Error -10 (bad UTF-8 string) offset=0 reason=14 \x{d800}\? No match \x{da00} Error -10 (bad UTF-8 string) offset=0 reason=14 \x{da00}\? No match \x{dfff} Error -10 (bad UTF-8 string) offset=0 reason=14 \x{dfff}\? No match \x{110000} Error -10 (bad UTF-8 string) offset=0 reason=13 \x{110000}\? No match \x{2000000} Error -10 (bad UTF-8 string) offset=0 reason=11 \x{2000000}\? No match \x{7fffffff} Error -10 (bad UTF-8 string) offset=0 reason=12 \x{7fffffff}\? No match /(*UTF8)\x{1234}/ abcd\x{1234}pqr 0: \x{1234} /(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I Capturing subpattern count = 0 Options: bsr_unicode utf Forced newline sequence: CRLF First char = 'a' Need char = 'b' /\h/SI8 Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x09 \x20 \xc2 \xe1 \xe2 \xe3 ABC\x{09} 0: \x{09} ABC\x{20} 0: ABC\x{a0} 0: \x{a0} ABC\x{1680} 0: \x{1680} ABC\x{180e} 0: \x{180e} ABC\x{2000} 0: \x{2000} ABC\x{202f} 0: \x{202f} ABC\x{205f} 0: \x{205f} ABC\x{3000} 0: \x{3000} /\v/SI8 Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 ABC\x{0a} 0: \x{0a} ABC\x{0b} 0: \x{0b} ABC\x{0c} 0: \x{0c} ABC\x{0d} 0: \x{0d} ABC\x{85} 0: \x{85} ABC\x{2028} 0: \x{2028} /\h*A/SI8 Capturing subpattern count = 0 Options: utf No first char Need char = 'A' Subject length lower bound = 1 Starting byte set: \x09 \x20 A \xc2 \xe1 \xe2 \xe3 CDBABC 0: A /\v+A/SI8 Capturing subpattern count = 0 Options: utf No first char Need char = 'A' Subject length lower bound = 2 Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 /\s?xxx\s/8SI Capturing subpattern count = 0 Options: utf No first char Need char = 'x' Subject length lower bound = 4 Starting byte set: \x09 \x0a \x0c \x0d \x20 x /\sxxx\s/I8ST1 Capturing subpattern count = 0 Options: utf No first char Need char = 'x' Subject length lower bound = 5 Starting byte set: \x09 \x0a \x0c \x0d \x20 \xc2 AB\x{85}xxx\x{a0}XYZ 0: \x{85}xxx\x{a0} AB\x{a0}xxx\x{85}XYZ 0: \x{a0}xxx\x{85} /\S \S/I8ST1 Capturing subpattern count = 0 Options: utf No first char Need char = ' ' Subject length lower bound = 3 Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff \x{a2} \x{84} 0: \x{a2} \x{84} A Z 0: A Z /a+/8 a\x{123}aa\>1 0: aa a\x{123}aa\>2 Error -11 (bad UTF-8 offset) a\x{123}aa\>3 0: aa a\x{123}aa\>4 0: a a\x{123}aa\>5 No match a\x{123}aa\>6 Error -24 (bad offset value) /\x{1234}+/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 1 Starting byte set: \xe1 /\x{1234}+?/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 1 Starting byte set: \xe1 /\x{1234}++/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 1 Starting byte set: \xe1 /\x{1234}{2}/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 2 Starting byte set: \xe1 /[^\x{c4}]/8DZ ------------------------------------------------------------------ Bra [^\x{c4}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /X+\x{200}/8DZ ------------------------------------------------------------------ Bra X++ \x{200} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'X' Need char = \x{80} /\R/SI8 Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 /\777/8DZ ------------------------------------------------------------------ Bra \x{1ff} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{c7} Need char = \x{bf} /\w+\x{C4}/8BZ ------------------------------------------------------------------ Bra \w++ \x{c4} Ket End ------------------------------------------------------------------ a\x{C4}\x{C4} 0: a\x{c4} /\w+\x{C4}/8BZT1 ------------------------------------------------------------------ Bra \w+ \x{c4} Ket End ------------------------------------------------------------------ a\x{C4}\x{C4} 0: a\x{c4}\x{c4} /\W+\x{C4}/8BZ ------------------------------------------------------------------ Bra \W+ \x{c4} Ket End ------------------------------------------------------------------ !\x{C4} 0: !\x{c4} /\W+\x{C4}/8BZT1 ------------------------------------------------------------------ Bra \W++ \x{c4} Ket End ------------------------------------------------------------------ !\x{C4} 0: !\x{c4} /\W+\x{A1}/8BZ ------------------------------------------------------------------ Bra \W+ \x{a1} Ket End ------------------------------------------------------------------ !\x{A1} 0: !\x{a1} /\W+\x{A1}/8BZT1 ------------------------------------------------------------------ Bra \W+ \x{a1} Ket End ------------------------------------------------------------------ !\x{A1} 0: !\x{a1} /X\s+\x{A0}/8BZ ------------------------------------------------------------------ Bra X \s++ \x{a0} Ket End ------------------------------------------------------------------ X\x20\x{A0}\x{A0} 0: X \x{a0} /X\s+\x{A0}/8BZT1 ------------------------------------------------------------------ Bra X \s+ \x{a0} Ket End ------------------------------------------------------------------ X\x20\x{A0}\x{A0} 0: X \x{a0}\x{a0} /\S+\x{A0}/8BZ ------------------------------------------------------------------ Bra \S+ \x{a0} Ket End ------------------------------------------------------------------ X\x{A0}\x{A0} 0: X\x{a0}\x{a0} /\S+\x{A0}/8BZT1 ------------------------------------------------------------------ Bra \S++ \x{a0} Ket End ------------------------------------------------------------------ X\x{A0}\x{A0} 0: X\x{a0} /\x{a0}+\s!/8BZ ------------------------------------------------------------------ Bra \x{a0}++ \s ! Ket End ------------------------------------------------------------------ \x{a0}\x20! 0: \x{a0} ! /\x{a0}+\s!/8BZT1 ------------------------------------------------------------------ Bra \x{a0}+ \s ! Ket End ------------------------------------------------------------------ \x{a0}\x20! 0: \x{a0} ! /-- End of testinput15 --/ pcre-8.31/testdata/testoutput160000644000222100022210000000656211721171641013460 00000000000000/-- This set of tests is run only with the 8-bit library when Unicode property support is available. It starts with tests of the POSIX interface, because that is supported only with the 8-bit library. --/ /\w/P +++\x{c2} No match: POSIX code 17: match failed /\w/WP +++\x{c2} 0: \xc2 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ ------------------------------------------------------------------ Bra /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless utf First char = 'A' (caseless) No need char /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ ------------------------------------------------------------------ Bra A\x{391}\x{10427}\x{ff3a}\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'A' Need char = \x{b0} /AB\x{1fb0}/8DZ ------------------------------------------------------------------ Bra AB\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'A' Need char = \x{b0} /AB\x{1fb0}/8DZi ------------------------------------------------------------------ Bra /i AB\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless utf First char = 'A' (caseless) Need char = 'B' (caseless) /\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 17 Starting byte set: \xd0 \xd1 \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} /[â±¥]/8iBZ ------------------------------------------------------------------ Bra /i \x{2c65} Ket End ------------------------------------------------------------------ /[^â±¥]/8iBZ ------------------------------------------------------------------ Bra /i [^\x{2c65}] Ket End ------------------------------------------------------------------ /\h/SI Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: \x09 \x20 \xa0 /\v/SI Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \x85 /\R/SI Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \x85 /[[:blank:]]/WBZ ------------------------------------------------------------------ Bra [\x09 \xa0] Ket End ------------------------------------------------------------------ /-- End of testinput16 --/ pcre-8.31/testdata/testoutput170000644000222100022210000005041411767405322013462 00000000000000/-- This set of tests is for the 16-bit library's basic (non-UTF-16) features that are not compatible with the 8-bit library, or which give different output in 16-bit mode. --/ /a\Cb/ aXb 0: aXb a\nb 0: a\x0ab /-- Check maximum non-UTF character size --/ /\x{ffff}/ A\x{ffff}B 0: \x{ffff} /\x{10000}/ Failed: character value in \x{...} sequence is too large at offset 8 /[^\x{c4}]/DZ ------------------------------------------------------------------ Bra [^\xc4] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /\x{100}/I Capturing subpattern count = 0 No options First char = \x{100} No need char / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /xSI Capturing subpattern count = 0 Contains explicit CR or LF match Options: extended No first char No need char Subject length lower bound = 3 Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xff /[\h]/BZ ------------------------------------------------------------------ Bra [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] Ket End ------------------------------------------------------------------ >\x09< 0: \x09 /[\h]+/BZ ------------------------------------------------------------------ Bra [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]+ Ket End ------------------------------------------------------------------ >\x09\x20\xa0< 0: \x09 \xa0 /[\v]/BZ ------------------------------------------------------------------ Bra [\x0a-\x0d\x85\x{2028}-\x{2029}] Ket End ------------------------------------------------------------------ /[\H]/BZ ------------------------------------------------------------------ Bra [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}] Ket End ------------------------------------------------------------------ /[^\h]/BZ ------------------------------------------------------------------ Bra [^\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] Ket End ------------------------------------------------------------------ /[\V]/BZ ------------------------------------------------------------------ Bra [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}] Ket End ------------------------------------------------------------------ /[\x0a\V]/BZ ------------------------------------------------------------------ Bra [\x00-\x0a\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}] Ket End ------------------------------------------------------------------ /\h+/SI Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: \x09 \x20 \xa0 \xff \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} 0: \x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\xa0\x{2000} 0: \x{200a}\xa0\x{2000} /[\h\x{dc00}]+/BZSI ------------------------------------------------------------------ Bra [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{dc00}]+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 No set of starting bytes \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} 0: \x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\xa0\x{2000} 0: \x{200a}\xa0\x{2000} /\H+/SI Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 No set of starting bytes \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} 0: \x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} 0: \x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} 0: \x{202e}\x{2030}\x{205e}\x{2060} \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} 0: \x9f\xa1\x{2fff}\x{3001} /[\H\x{d800}]+/BZSI ------------------------------------------------------------------ Bra [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}\x{d800}]+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 No set of starting bytes \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} 0: \x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} 0: \x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} 0: \x{202e}\x{2030}\x{205e}\x{2060} \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} 0: \x9f\xa1\x{2fff}\x{3001} /\v+/SI Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff \x{2027}\x{2030}\x{2028}\x{2029} 0: \x{2028}\x{2029} \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d 0: \x85\x0a\x0b\x0c\x0d /[\v\x{dc00}]+/BZSI ------------------------------------------------------------------ Bra [\x0a-\x0d\x85\x{2028}-\x{2029}\x{dc00}]+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 No set of starting bytes \x{2027}\x{2030}\x{2028}\x{2029} 0: \x{2028}\x{2029} \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d 0: \x85\x0a\x0b\x0c\x0d /\V+/SI Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 No set of starting bytes \x{2028}\x{2029}\x{2027}\x{2030} 0: \x{2027}\x{2030} \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 0: \x09\x0e\x84\x86 /[\V\x{d800}]+/BZSI ------------------------------------------------------------------ Bra [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}\x{d800}]+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 No set of starting bytes \x{2028}\x{2029}\x{2027}\x{2030} 0: \x{2027}\x{2030} \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 0: \x09\x0e\x84\x86 /\R+/SI Capturing subpattern count = 0 Options: bsr_unicode No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff \x{2027}\x{2030}\x{2028}\x{2029} 0: \x{2028}\x{2029} \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d 0: \x85\x0a\x0b\x0c\x0d /\x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}/I Capturing subpattern count = 0 No options First char = \x{d800} Need char = \x{dd00} \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} 0: \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} /[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZ ------------------------------------------------------------------ Bra [^\x80] [^\xff] [^\x{100}] [^\x{1000}] [^\x{ffff}] Ket End ------------------------------------------------------------------ /[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZi ------------------------------------------------------------------ Bra /i [^\x80] /i [^\xff] /i [^\x{100}] /i [^\x{1000}] /i [^\x{ffff}] Ket End ------------------------------------------------------------------ /[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZ ------------------------------------------------------------------ Bra [^\x{100}]* [^\x{1000}]+ [^\x{ffff}]?? [^\x{8000}]{4} [^\x{8000}]* [^\x{7fff}]{2} [^\x{7fff}]{0,7}? [^\x{100}]{5} [^\x{100}]?+ Ket End ------------------------------------------------------------------ /[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZi ------------------------------------------------------------------ Bra /i [^\x{100}]* /i [^\x{1000}]+ /i [^\x{ffff}]?? /i [^\x{8000}]{4} /i [^\x{8000}]* /i [^\x{7fff}]{2} /i [^\x{7fff}]{0,7}? Once /i [^\x{100}]{5} /i [^\x{100}]? Ket Ket End ------------------------------------------------------------------ /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K XX 0: XX MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K XX 0: XX MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE /\u0100/BZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ /[\u0100-\u0200]/BZ ------------------------------------------------------------------ Bra [\x{100}-\x{200}] Ket End ------------------------------------------------------------------ /\ud800/BZ ------------------------------------------------------------------ Bra \x{d800} Ket End ------------------------------------------------------------------ /-- End of testinput17 --/ pcre-8.31/testdata/testoutput180000644000222100022210000005313411775523547013476 00000000000000/-- This set of tests is for UTF-16 support, and is relevant only to the 16-bit library. --/ /ÃÃÃxxx/8?DZSS **Failed: invalid UTF-8 string cannot be converted to UTF-16 /abc/8 Ã] **Failed: invalid UTF-8 string cannot be converted to UTF-16 /X(\C{3})/8 X\x{11234}Y 0: X\x{11234}Y 1: \x{11234}Y /X(\C{4})/8 X\x{11234}YZ 0: X\x{11234}YZ 1: \x{11234}YZ /X\C*/8 XYZabcdce 0: XYZabcdce /X\C*?/8 XYZabcde 0: X /X\C{3,5}/8 Xabcdefg 0: Xabcde X\x{11234}Y 0: X\x{11234}Y X\x{11234}YZ 0: X\x{11234}YZ X\x{11234}\x{512} 0: X\x{11234}\x{512} X\x{11234}\x{512}YZ 0: X\x{11234}\x{512}YZ X\x{11234}\x{512}\x{11234}Z 0: X\x{11234}\x{512}\x{11234} /X\C{3,5}?/8 Xabcdefg 0: Xabc X\x{11234}Y 0: X\x{11234}Y X\x{11234}YZ 0: X\x{11234}Y X\x{11234}\x{512}YZ 0: X\x{11234}\x{512} *** Failers No match X\x{11234} No match /a\Cb/8 aXb 0: aXb a\nb 0: a\x{0a}b /a\C\Cb/8 a\x{12257}b 0: a\x{12257}b ** Failers No match a\x{100}b No match /ab\Cde/8 abXde 0: abXde /-- Check maximum character size --/ /\x{ffff}/8DZ ------------------------------------------------------------------ Bra \x{ffff} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{ffff} No need char /\x{10000}/8DZ ------------------------------------------------------------------ Bra \x{10000} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{d800} Need char = \x{dc00} /\x{100}/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{100} No need char /\x{1000}/8DZ ------------------------------------------------------------------ Bra \x{1000} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{1000} No need char /\x{10000}/8DZ ------------------------------------------------------------------ Bra \x{10000} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{d800} Need char = \x{dc00} /\x{100000}/8DZ ------------------------------------------------------------------ Bra \x{100000} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{dbc0} Need char = \x{dc00} /\x{10ffff}/8DZ ------------------------------------------------------------------ Bra \x{10ffff} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{dbff} Need char = \x{dfff} /[\x{ff}]/8DZ ------------------------------------------------------------------ Bra \xff Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{ff} No need char /[\x{100}]/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{100} No need char /\x80/8DZ ------------------------------------------------------------------ Bra \x80 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{80} No need char /\xff/8DZ ------------------------------------------------------------------ Bra \xff Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{ff} No need char /\x{D55c}\x{ad6d}\x{C5B4}/DZ8 ------------------------------------------------------------------ Bra \x{d55c}\x{ad6d}\x{c5b4} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{d55c} Need char = \x{c5b4} \x{D55c}\x{ad6d}\x{C5B4} 0: \x{d55c}\x{ad6d}\x{c5b4} /\x{65e5}\x{672c}\x{8a9e}/DZ8 ------------------------------------------------------------------ Bra \x{65e5}\x{672c}\x{8a9e} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{65e5} Need char = \x{8a9e} \x{65e5}\x{672c}\x{8a9e} 0: \x{65e5}\x{672c}\x{8a9e} /\x{80}/DZ8 ------------------------------------------------------------------ Bra \x80 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{80} No need char /\x{084}/DZ8 ------------------------------------------------------------------ Bra \x84 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{84} No need char /\x{104}/DZ8 ------------------------------------------------------------------ Bra \x{104} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{104} No need char /\x{861}/DZ8 ------------------------------------------------------------------ Bra \x{861} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{861} No need char /\x{212ab}/DZ8 ------------------------------------------------------------------ Bra \x{212ab} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{d844} Need char = \x{deab} /-- This one is here not because it's different to Perl, but because the way the captured single-byte is displayed. (In Perl it becomes a character, and you can't tell the difference.) --/ /X(\C)(.*)/8 X\x{1234} 0: X\x{1234} 1: \x{1234} 2: X\nabc 0: X\x{0a}abc 1: \x{0a} 2: abc /-- This one is here because Perl gives out a grumbly error message (quite correctly, but that messes up comparisons). --/ /a\Cb/8 *** Failers No match a\x{100}b 0: a\x{100}b /[^ab\xC0-\xF0]/8SDZ ------------------------------------------------------------------ Bra [\x00-`c-\xbf\xf1-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff \x{f1} 0: \x{f1} \x{bf} 0: \x{bf} \x{100} 0: \x{100} \x{1000} 0: \x{1000} *** Failers 0: * \x{c0} No match \x{f0} No match /Ä€{3,4}/8SDZ ------------------------------------------------------------------ Bra \x{100}{3} \x{100}? Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{100} Need char = \x{100} Subject length lower bound = 3 No set of starting bytes \x{100}\x{100}\x{100}\x{100\x{100} 0: \x{100}\x{100}\x{100} /(\x{100}+|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100}+ Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: x \xff /(\x{100}*a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100}*+ a Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: a x \xff /(\x{100}{0,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100}{0,2} a Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: a x \xff /(\x{100}{1,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100} \x{100}{0,1} a Alt x Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: x \xff /\x{100}/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{100} No need char /a\x{100}\x{101}*/8DZ ------------------------------------------------------------------ Bra a\x{100} \x{101}* Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'a' Need char = \x{100} /a\x{100}\x{101}+/8DZ ------------------------------------------------------------------ Bra a\x{100} \x{101}+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'a' Need char = \x{101} /[^\x{c4}]/DZ ------------------------------------------------------------------ Bra [^\xc4] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[\x{100}]/8DZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{100} No need char \x{100} 0: \x{100} Z\x{100} 0: \x{100} \x{100}Z 0: \x{100} *** Failers No match /[\xff]/DZ8 ------------------------------------------------------------------ Bra \xff Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{ff} No need char >\x{ff}< 0: \x{ff} /[^\xff]/8DZ ------------------------------------------------------------------ Bra [^\xff] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /\x{100}abc(xyz(?1))/8DZ ------------------------------------------------------------------ Bra \x{100}abc CBra 1 xyz Recurse Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf First char = \x{100} Need char = 'z' /\777/8I Capturing subpattern count = 0 Options: utf First char = \x{1ff} No need char \x{1ff} 0: \x{1ff} \777 0: \x{1ff} /\x{100}+\x{200}/8DZ ------------------------------------------------------------------ Bra \x{100}++ \x{200} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{100} Need char = \x{200} /\x{100}+X/8DZ ------------------------------------------------------------------ Bra \x{100}++ X Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{100} Need char = 'X' /^[\QÄ€\E-\QÅ\E/BZ8 Failed: missing terminating ] for character class at offset 13 /X/8 \x{0}\x{d7ff}\x{e000}\x{10ffff} No match \x{d800} Error -10 (bad UTF-16 string) offset=0 reason=1 \x{d800}\? No match \x{da00} Error -10 (bad UTF-16 string) offset=0 reason=1 \x{da00}\? No match \x{dc00} Error -10 (bad UTF-16 string) offset=0 reason=3 \x{dc00}\? No match \x{de00} Error -10 (bad UTF-16 string) offset=0 reason=3 \x{de00}\? No match \x{dfff} Error -10 (bad UTF-16 string) offset=0 reason=3 \x{dfff}\? No match \x{110000} **Failed: character value greater than 0x10ffff cannot be converted to UTF-16 \x{d800}\x{1234} Error -10 (bad UTF-16 string) offset=1 reason=2 \x{fffe} Error -10 (bad UTF-16 string) offset=0 reason=4 /(*UTF16)\x{11234}/ abcd\x{11234}pqr 0: \x{11234} /(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I Capturing subpattern count = 0 Options: bsr_unicode utf Forced newline sequence: CRLF First char = 'a' Need char = 'b' /\h/SI8 Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x09 \x20 \xa0 \xff ABC\x{09} 0: \x{09} ABC\x{20} 0: ABC\x{a0} 0: \x{a0} ABC\x{1680} 0: \x{1680} ABC\x{180e} 0: \x{180e} ABC\x{2000} 0: \x{2000} ABC\x{202f} 0: \x{202f} ABC\x{205f} 0: \x{205f} ABC\x{3000} 0: \x{3000} /\v/SI8 Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff ABC\x{0a} 0: \x{0a} ABC\x{0b} 0: \x{0b} ABC\x{0c} 0: \x{0c} ABC\x{0d} 0: \x{0d} ABC\x{85} 0: \x{85} ABC\x{2028} 0: \x{2028} /\h*A/SI8 Capturing subpattern count = 0 Options: utf No first char Need char = 'A' Subject length lower bound = 1 Starting byte set: \x09 \x20 A \xa0 \xff CDBABC 0: A \x{2000}ABC 0: \x{2000}A /\R*A/SI8 Capturing subpattern count = 0 Options: utf No first char Need char = 'A' Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff CDBABC 0: A \x{2028}A 0: \x{2028}A /\v+A/SI8 Capturing subpattern count = 0 Options: utf No first char Need char = 'A' Subject length lower bound = 2 Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff /\s?xxx\s/8SI Capturing subpattern count = 0 Options: utf No first char Need char = 'x' Subject length lower bound = 4 Starting byte set: \x09 \x0a \x0c \x0d \x20 x /\sxxx\s/I8ST1 Capturing subpattern count = 0 Options: utf No first char Need char = 'x' Subject length lower bound = 5 Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0 AB\x{85}xxx\x{a0}XYZ 0: \x{85}xxx\x{a0} AB\x{a0}xxx\x{85}XYZ 0: \x{a0}xxx\x{85} /\S \S/I8ST1 Capturing subpattern count = 0 Options: utf No first char Need char = ' ' Subject length lower bound = 3 Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff \x{a2} \x{84} 0: \x{a2} \x{84} A Z 0: A Z /a+/8 a\x{123}aa\>1 0: aa a\x{123}aa\>2 0: aa a\x{123}aa\>3 0: a a\x{123}aa\>4 No match a\x{123}aa\>5 Error -24 (bad offset value) a\x{123}aa\>6 Error -24 (bad offset value) /\x{1234}+/iS8I Capturing subpattern count = 0 Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 No set of starting bytes /\x{1234}+?/iS8I Capturing subpattern count = 0 Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 No set of starting bytes /\x{1234}++/iS8I Capturing subpattern count = 0 Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 No set of starting bytes /\x{1234}{2}/iS8I Capturing subpattern count = 0 Options: caseless utf First char = \x{1234} Need char = \x{1234} Subject length lower bound = 2 No set of starting bytes /[^\x{c4}]/8DZ ------------------------------------------------------------------ Bra [^\xc4] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /X+\x{200}/8DZ ------------------------------------------------------------------ Bra X++ \x{200} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'X' Need char = \x{200} /\R/SI8 Capturing subpattern count = 0 Options: utf No first char No need char Subject length lower bound = 1 Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff /-- Check bad offset --/ /a/8 \x{10000}\>1 Error -11 (bad UTF-16 offset) \x{10000}ab\>2 0: a \x{10000}ab\>3 No match \x{10000}ab\>4 No match \x{10000}ab\>5 Error -24 (bad offset value) /í¼€/8 Failed: invalid UTF-16 string at offset 0 /\w+\x{C4}/8BZ ------------------------------------------------------------------ Bra \w++ \xc4 Ket End ------------------------------------------------------------------ a\x{C4}\x{C4} 0: a\x{c4} /\w+\x{C4}/8BZT1 ------------------------------------------------------------------ Bra \w+ \xc4 Ket End ------------------------------------------------------------------ a\x{C4}\x{C4} 0: a\x{c4}\x{c4} /\W+\x{C4}/8BZ ------------------------------------------------------------------ Bra \W+ \xc4 Ket End ------------------------------------------------------------------ !\x{C4} 0: !\x{c4} /\W+\x{C4}/8BZT1 ------------------------------------------------------------------ Bra \W++ \xc4 Ket End ------------------------------------------------------------------ !\x{C4} 0: !\x{c4} /\W+\x{A1}/8BZ ------------------------------------------------------------------ Bra \W+ \xa1 Ket End ------------------------------------------------------------------ !\x{A1} 0: !\x{a1} /\W+\x{A1}/8BZT1 ------------------------------------------------------------------ Bra \W+ \xa1 Ket End ------------------------------------------------------------------ !\x{A1} 0: !\x{a1} /X\s+\x{A0}/8BZ ------------------------------------------------------------------ Bra X \s++ \xa0 Ket End ------------------------------------------------------------------ X\x20\x{A0}\x{A0} 0: X \x{a0} /X\s+\x{A0}/8BZT1 ------------------------------------------------------------------ Bra X \s+ \xa0 Ket End ------------------------------------------------------------------ X\x20\x{A0}\x{A0} 0: X \x{a0}\x{a0} /\S+\x{A0}/8BZ ------------------------------------------------------------------ Bra \S+ \xa0 Ket End ------------------------------------------------------------------ X\x{A0}\x{A0} 0: X\x{a0}\x{a0} /\S+\x{A0}/8BZT1 ------------------------------------------------------------------ Bra \S++ \xa0 Ket End ------------------------------------------------------------------ X\x{A0}\x{A0} 0: X\x{a0} /\x{a0}+\s!/8BZ ------------------------------------------------------------------ Bra \xa0++ \s ! Ket End ------------------------------------------------------------------ \x{a0}\x20! 0: \x{a0} ! /\x{a0}+\s!/8BZT1 ------------------------------------------------------------------ Bra \xa0+ \s ! Ket End ------------------------------------------------------------------ \x{a0}\x20! 0: \x{a0} ! /-- End of testinput18 --/ pcre-8.31/testdata/testoutput190000644000222100022210000000553211676645220013467 00000000000000/-- This set of tests is for Unicode property support, relevant only to the 16-bit library. --/ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ ------------------------------------------------------------------ Bra /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless utf First char = 'A' (caseless) Need char = \x{1fb0} (caseless) /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ ------------------------------------------------------------------ Bra A\x{391}\x{10427}\x{ff3a}\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'A' Need char = \x{1fb0} /AB\x{1fb0}/8DZ ------------------------------------------------------------------ Bra AB\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'A' Need char = \x{1fb0} /AB\x{1fb0}/8DZi ------------------------------------------------------------------ Bra /i AB\x{1fb0} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless utf First char = 'A' (caseless) Need char = \x{1fb0} (caseless) /\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI Capturing subpattern count = 0 Options: caseless utf First char = \x{401} (caseless) Need char = \x{42f} (caseless) Subject length lower bound = 17 No set of starting bytes \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} /[â±¥]/8iBZ ------------------------------------------------------------------ Bra /i \x{2c65} Ket End ------------------------------------------------------------------ /[^â±¥]/8iBZ ------------------------------------------------------------------ Bra /i [^\x{2c65}] Ket End ------------------------------------------------------------------ /[[:blank:]]/WBZ ------------------------------------------------------------------ Bra [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] Ket End ------------------------------------------------------------------ /-- End of testinput19 --/ pcre-8.31/testdata/testoutput200000644000222100022210000000056711676645223013465 00000000000000/-- These tests are for the handling of characters greater than 255 in 16-bit, non-UTF-16 mode. --/ /^\x{ffff}+/i \x{ffff} 0: \x{ffff} /^\x{ffff}?/i \x{ffff} 0: \x{ffff} /^\x{ffff}*/i \x{ffff} 0: \x{ffff} /^\x{ffff}{3}/i \x{ffff}\x{ffff}\x{ffff} 0: \x{ffff}\x{ffff}\x{ffff} /^\x{ffff}{0,3}/i \x{ffff} 0: \x{ffff} /-- End of testinput20 --/ pcre-8.31/testdata/testoutput210000644000222100022210000000371311706273660013456 00000000000000/-- Tests for reloading pre-compile patterns. The first one gives an error right away. The others require the linke size to be 2. */ (?:[AaLl]+)[^xX-]*?)(?P[\x{150}-\x{250}\x{300}]|[^\x{800}aAs-uS-U\x{d800}-\x{dfff}])++[^#\b\x{500}\x{1000}]{3,5}$ --/ [aZ\x{400}-\x{10ffff}]{4,}[\x{f123}\x{10039}\x{20000}-\x{21234}]?|[A-Cx-z\x{100000}-\x{1000a7}\x{101234}])(?[^az]) --/8 < for testing. RC=0 ---------------------------- Test 39 ------------------------------ This is a line before the binary zero. This line contains a binary zero here >< for testing. RC=0 ---------------------------- Test 40 ------------------------------ This line contains a binary zero here >< for testing. This is a line after the binary zero. RC=0 ---------------------------- Test 41 ------------------------------ before the binary zero after the binary zero RC=0 ---------------------------- Test 42 ------------------------------ ./testdata/grepinput:595:before the binary zero ./testdata/grepinput:597:after the binary zero RC=0 ---------------------------- Test 43 ------------------------------ 595:before 595:zero 596:zero 597:after 597:zero RC=0 ---------------------------- Test 44 ------------------------------ 595:before 595:zero 596:zero 597:zero RC=0 ---------------------------- Test 45 ------------------------------ 10:pattern 595:binary 596:binary 597:binary RC=0 ---------------------------- Test 46 ------------------------------ pcregrep: Error in 2nd command-line regex at offset 9: missing ) RC=2 ---------------------------- Test 47 ------------------------------ AB.VE RC=0 ---------------------------- Test 48 ------------------------------ ABOVE the elephant AB.VE AB.VE the turtle RC=0 ---------------------------- Test 49 ------------------------------ ABOVE the elephant AB.VE AB.VE the turtle PUT NEW DATA ABOVE THIS LINE. RC=0 ---------------------------- Test 50 ------------------------------ RC=1 ---------------------------- Test 51 ------------------------------ over the lazy dog. This time it jumps and jumps and jumps. RC=0 ---------------------------- Test 52 ------------------------------ fox jumps This time it jumps and jumps and jumps. RC=0 ---------------------------- Test 53 ------------------------------ 36972,6 36990,4 37024,4 37066,5 37083,4 RC=0 ---------------------------- Test 54 ------------------------------ 595:15,6 595:33,4 596:28,4 597:15,5 597:32,4 RC=0 ---------------------------- Test 55 ----------------------------- Here is the pattern again. That time it was on a line by itself. This line contains pattern not on a line by itself. RC=0 ---------------------------- Test 56 ----------------------------- ./testdata/grepinput:456 ./testdata/grepinput3:0 ./testdata/grepinput8:0 ./testdata/grepinputv:1 ./testdata/grepinputx:0 RC=0 ---------------------------- Test 57 ----------------------------- ./testdata/grepinput:456 ./testdata/grepinputv:1 RC=0 ---------------------------- Test 58 ----------------------------- PATTERN at the start of a line. In the middle of a line, PATTERN appears. Check up on PATTERN near the end. RC=0 ---------------------------- Test 59 ----------------------------- PATTERN at the start of a line. In the middle of a line, PATTERN appears. Check up on PATTERN near the end. RC=0 ---------------------------- Test 60 ----------------------------- PATTERN at the start of a line. In the middle of a line, PATTERN appears. Check up on PATTERN near the end. RC=0 ---------------------------- Test 61 ----------------------------- PATTERN at the start of a line. In the middle of a line, PATTERN appears. Check up on PATTERN near the end. RC=0 ---------------------------- Test 62 ----------------------------- pcregrep: pcre_exec() gave error -8 while matching text that starts: This is a file of miscellaneous text that is used as test data for checking that the pcregrep command is working correctly. The file must be more than 24K long so that it needs more than a single read pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. RC=1 ---------------------------- Test 63 ----------------------------- pcregrep: pcre_exec() gave error -21 while matching text that starts: This is a file of miscellaneous text that is used as test data for checking that the pcregrep command is working correctly. The file must be more than 24K long so that it needs more than a single read pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. RC=1 ---------------------------- Test 64 ------------------------------ appears RC=0 ---------------------------- Test 65 ------------------------------ pear RC=0 ---------------------------- Test 66 ------------------------------ RC=0 ---------------------------- Test 67 ------------------------------ RC=0 ---------------------------- Test 68 ------------------------------ pear RC=0 ---------------------------- Test 69 ----------------------------- 1:This is a second file of input for the pcregrep tests. 2: 4: 5:Pattern 6:That time it was on a line by itself. 7: 8:To pat or not to pat, that is the question. 9: 10:complete pair 11:of lines 12: 13:That was a complete pair 14:of lines all by themselves. 15: 16:complete pair 17:of lines 18: 19:And there they were again, to check line numbers. 20: 21:one 22:two 23:three 24:four 25:five 26:six 27:seven 28:eight 29:nine 30:ten 31:eleven 32:twelve 33:thirteen 34:fourteen 35:fifteen 36:sixteen 37:seventeen 38:eighteen 39:nineteen 40:twenty 41: 43:This is the last line of this file. RC=0 ---------------------------- Test 70 ----------------------------- triple: t1_txt s1_tag s_txt p_tag p_txt o_tag o_txt triple: t3_txt s2_tag s_txt p_tag p_txt o_tag o_txt triple: t4_txt s1_tag s_txt p_tag p_txt o_tag o_txt triple: t6_txt s2_tag s_txt p_tag p_txt o_tag o_txt RC=0 ---------------------------- Test 71 ----------------------------- 01 RC=0 ---------------------------- Test 72 ----------------------------- 010203040506 RC=0 ---------------------------- Test 73 ----------------------------- 01 RC=0 ---------------------------- Test 74 ----------------------------- 01 02 RC=0 ---------------------------- Test 75 ----------------------------- 010203040506 RC=0 ---------------------------- Test 76 ----------------------------- 01 02 RC=0 ---------------------------- Test 77 ----------------------------- 01 03 RC=0 ---------------------------- Test 78 ----------------------------- 010203040506 RC=0 ---------------------------- Test 79 ----------------------------- 01 03 RC=0 ---------------------------- Test 80 ----------------------------- 01 RC=0 ---------------------------- Test 81 ----------------------------- 010203040506 RC=0 ---------------------------- Test 82 ----------------------------- 01 RC=0 ---------------------------- Test 83 ----------------------------- pcregrep: line 4 of file ./testdata/grepinput3 is too long for the internal buffer pcregrep: check the --buffer-size option RC=2 ---------------------------- Test 84 ----------------------------- testdata/grepinputv:fox jumps testdata/grepinputx:complete pair testdata/grepinputx:That was a complete pair testdata/grepinputx:complete pair RC=0 ---------------------------- Test 85 ----------------------------- ./testdata/grepinput3:Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. RC=0 ---------------------------- Test 86 ----------------------------- Binary file ./testdata/grepbinary matches RC=0 ---------------------------- Test 87 ----------------------------- RC=1 ---------------------------- Test 88 ----------------------------- Binary file ./testdata/grepbinary matches RC=0 ---------------------------- Test 89 ----------------------------- RC=1 ---------------------------- Test 90 ----------------------------- RC=1 ---------------------------- Test 91 ----------------------------- The quick brown fx jumps over the lazy dog. RC=0 ---------------------------- Test 92 ----------------------------- The quick brown fx jumps over the lazy dog. RC=0 ---------------------------- Test 93 ----------------------------- The quick brown fx jumps over the lazy dog. RC=0 pcre-8.31/testdata/grepoutput80000644000222100022210000000052211463311347013347 00000000000000---------------------------- Test U1 ------------------------------ 1:X one 2:X two 3:X three 4:X four 5:X five 6:X six 7:X sevenÂ…8:X eight
9:X nine
10:X ten RC=0 ---------------------------- Test U2 ------------------------------ 12-Before 111 13-Before 222
14-Before 333Â…15:Match 16-After 111 17-After 222
18-After 333 RC=0 pcre-8.31/testdata/grepoutputN0000644000222100022210000000100710615612271013372 00000000000000---------------------------- Test N1 ------------------------------ 1:abc 2:def ---------------------------- Test N2 ------------------------------ 1:abc def 2:ghi jkl---------------------------- Test N3 ------------------------------ 2:def 3: ghi jkl---------------------------- Test N4 ------------------------------ 2:ghi jkl---------------------------- Test N5 ------------------------------ 1:abc 2:def 3:ghi 4:jkl---------------------------- Test N6 ------------------------------ 1:abc 2:def 3:ghi 4:jklpcre-8.31/testdata/wintestoutput30000644000222100022210000000461611267044500014106 00000000000000/^[\w]+/ *** Failers No match École No match /^[\w]+/Lfrench École 0: École /^[\w]+/ *** Failers No match École No match /^[\W]+/ École 0: \xc9 /^[\W]+/Lfrench *** Failers 0: *** École No match /[\b]/ \b 0: \x08 *** Failers No match a No match /[\b]/Lfrench \b 0: \x08 *** Failers No match a No match /^\w+/ *** Failers No match École No match /^\w+/Lfrench École 0: École /(.+)\b(.+)/ École 0: \xc9cole 1: \xc9 2: cole /(.+)\b(.+)/Lfrench *** Failers 0: *** Failers 1: *** 2: Failers École No match /École/i École 0: \xc9cole *** Failers No match école No match /École/iLfrench École 0: École école 0: école /\w/IS Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z /\w/ISLfrench Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z ƒ Š Œ Ž š œ ž Ÿ ª ² ³ µ ¹ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ /^[\xc8-\xc9]/iLfrench École 0: É école 0: é /^[\xc8-\xc9]/Lfrench École 0: É *** Failers No match école No match /\W+/Lfrench >>>\xaa<<< 0: >>> >>>\xba<<< 0: >>> /[\W]+/Lfrench >>>\xaa<<< 0: >>> >>>\xba<<< 0: >>> /[^[:alpha:]]+/Lfrench >>>\xaa<<< 0: >>> >>>\xba<<< 0: >>> /\w+/Lfrench >>>\xaa<<< 0: ª >>>\xba<<< 0: º /[\w]+/Lfrench >>>\xaa<<< 0: ª >>>\xba<<< 0: º /[[:alpha:]]+/Lfrench >>>\xaa<<< 0: ª >>>\xba<<< 0: º /[[:alpha:]][[:lower:]][[:upper:]]/DZLfrench ------------------------------------------------------------------ Bra [A-Za-z\x83\x8a\x8c\x8e\x9a\x9c\x9e\x9f\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff] [a-z\x83\x9a\x9c\x9e\xaa\xb5\xba\xdf-\xf6\xf8-\xff] [A-Z\x8a\x8c\x8e\x9f\xc0-\xd6\xd8-\xde] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char / End of testinput3 / pcre-8.31/testdata/saved80000644000222100022210000000007511676645223012247 000000000000005ERCP5Qac(} abcr pcre-8.31/testdata/grepfilelist0000644000222100022210000000005111723200124013514 00000000000000testdata/grepinputv testdata/grepinputx pcre-8.31/testdata/wintestinput30000644000222100022210000000166510673453452013720 00000000000000/^[\w]+/ *** Failers École /^[\w]+/Lfrench École /^[\w]+/ *** Failers École /^[\W]+/ École /^[\W]+/Lfrench *** Failers École /[\b]/ \b *** Failers a /[\b]/Lfrench \b *** Failers a /^\w+/ *** Failers École /^\w+/Lfrench École /(.+)\b(.+)/ École /(.+)\b(.+)/Lfrench *** Failers École /École/i École *** Failers école /École/iLfrench École école /\w/IS /\w/ISLfrench /^[\xc8-\xc9]/iLfrench École école /^[\xc8-\xc9]/Lfrench École *** Failers école /\W+/Lfrench >>>\xaa<<< >>>\xba<<< /[\W]+/Lfrench >>>\xaa<<< >>>\xba<<< /[^[:alpha:]]+/Lfrench >>>\xaa<<< >>>\xba<<< /\w+/Lfrench >>>\xaa<<< >>>\xba<<< /[\w]+/Lfrench >>>\xaa<<< >>>\xba<<< /[[:alpha:]]+/Lfrench >>>\xaa<<< >>>\xba<<< /[[:alpha:]][[:lower:]][[:upper:]]/DZLfrench / End of testinput3 / pcre-8.31/config.guess0000755000222100022210000013013211775524614011637 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU/*) eval $set_cc_for_build cat <<-EOF > $dummy.c #include #ifdef __UCLIBC__ # ifdef __UCLIBC_CONFIG_VERSION__ LIBC=uclibc __UCLIBC_CONFIG_VERSION__ # else LIBC=uclibc # endif #else # ifdef __dietlibc__ LIBC=dietlibc # else LIBC=gnu # endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: pcre-8.31/pcre16_newline.c0000644000222100022210000000420111676645212012277 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_newline.c" /* End of pcre16_newline.c */ pcre-8.31/install-sh0000755000222100022210000003253711775524614011335 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: pcre-8.31/pcre16_version.c0000644000222100022210000000420111676645227012331 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_version.c" /* End of pcre16_version.c */ pcre-8.31/pcre16_xclass.c0000644000222100022210000000417711676645217012154 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_xclass.c" /* End of pcre16_xclass.c */ pcre-8.31/pcre_ord2utf8.c0000644000222100022210000000652711707312247012153 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This file contains a private PCRE function that converts an ordinal character value into a UTF8 string. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Convert character value to UTF-8 * *************************************************/ /* This function takes an integer value in the range 0 - 0x10ffff and encodes it as a UTF-8 character in 1 to 6 pcre_uchars. Arguments: cvalue the character value buffer pointer to buffer for result - at least 6 pcre_uchars long Returns: number of characters placed in the buffer */ int PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) { #ifdef SUPPORT_UTF register int i, j; /* Checking invalid cvalue character, encoded as invalid UTF-16 character. Should never happen in practice. */ if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000) cvalue = 0xfffe; for (i = 0; i < PRIV(utf8_table1_size); i++) if ((int)cvalue <= PRIV(utf8_table1)[i]) break; buffer += i; for (j = i; j > 0; j--) { *buffer-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } *buffer = PRIV(utf8_table2)[i] | cvalue; return i + 1; #else (void)(cvalue); /* Keep compiler happy; this function won't ever be */ (void)(buffer); /* called when SUPPORT_UTF is not defined. */ return 0; #endif } /* End of pcre_ord2utf8.c */ pcre-8.31/Detrail0000755000222100022210000000120310574031605010612 00000000000000#!/usr/bin/perl # This is a script for removing trailing whitespace from lines in files that # are listed on the command line. # This subroutine does the work for one file. sub detrail { my($file) = $_[0]; my($changed) = 0; open(IN, "$file") || die "Can't open $file for input"; @lines = ; close(IN); foreach (@lines) { if (/\s+\n$/) { s/\s+\n$/\n/; $changed = 1; } } if ($changed) { open(OUT, ">$file") || die "Can't open $file for output"; print OUT @lines; close(OUT); } } # This is the main program $, = ""; # Output field separator for ($i = 0; $i < @ARGV; $i++) { &detrail($ARGV[$i]); } # End pcre-8.31/pcretest.c0000644000222100022210000040514311762370424011315 00000000000000/************************************************* * PCRE testing program * *************************************************/ /* This program was hacked up as a tester for PCRE. I really should have written it more tidily in the first place. Will I ever learn? It has grown and been extended and consequently is now rather, er, *very* untidy in places. The addition of 16-bit support has made it even worse. :-( ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This program now supports the testing of both the 8-bit and 16-bit PCRE libraries in a single program. This is different from the modules such as pcre_compile.c in the library itself, which are compiled separately for each mode. If both modes are enabled, for example, pcre_compile.c is compiled twice (the second time with COMPILE_PCRE16 defined). By contrast, pcretest.c is compiled only once. Therefore, it must not make use of any of the macros from pcre_internal.h that depend on COMPILE_PCRE8 or COMPILE_PCRE16. It does, however, make use of SUPPORT_PCRE8 and SUPPORT_PCRE16 to ensure that it calls only supported library functions. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include /* Both libreadline and libedit are optionally supported. The user-supplied original patch uses readline/readline.h for libedit, but in at least one system it is installed as editline/readline.h, so the configuration code now looks for that first, falling back to readline/readline.h. */ #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) #ifdef HAVE_UNISTD_H #include #endif #if defined(SUPPORT_LIBREADLINE) #include #include #else #if defined(HAVE_EDITLINE_READLINE_H) #include #else #include #endif #endif #endif /* A number of things vary for Windows builds. Originally, pcretest opened its input and output without "b"; then I was told that "b" was needed in some environments, so it was added for release 5.0 to both the input and output. (It makes no difference on Unix-like systems.) Later I was told that it is wrong for the input on Windows. I've now abstracted the modes into two macros that are set here, to make it easier to fiddle with them, and removed "b" from the input mode under Windows. */ #if defined(_WIN32) || defined(WIN32) #include /* For _setmode() */ #include /* For _O_BINARY */ #define INPUT_MODE "r" #define OUTPUT_MODE "wb" #ifndef isatty #define isatty _isatty /* This is what Windows calls them, I'm told, */ #endif /* though in some environments they seem to */ /* be already defined, hence the #ifndefs. */ #ifndef fileno #define fileno _fileno #endif /* A user sent this fix for Borland Builder 5 under Windows. */ #ifdef __BORLANDC__ #define _setmode(handle, mode) setmode(handle, mode) #endif /* Not Windows */ #else #include /* These two includes are needed */ #include /* for setrlimit(). */ #define INPUT_MODE "rb" #define OUTPUT_MODE "wb" #endif #define PRIV(name) name /* We have to include pcre_internal.h because we need the internal info for displaying the results of pcre_study() and we also need to know about the internal macros, structures, and other internal data values; pcretest has "inside information" compared to a program that strictly follows the PCRE API. Although pcre_internal.h does itself include pcre.h, we explicitly include it here before pcre_internal.h so that the PCRE_EXP_xxx macros get set appropriately for an application, not for building PCRE. */ #include "pcre.h" #if defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE8 /* Configure internal macros to 16 bit mode. */ #define COMPILE_PCRE16 #endif #include "pcre_internal.h" /* The pcre_printint() function, which prints the internal form of a compiled regex, is held in a separate file so that (a) it can be compiled in either 8-bit or 16-bit mode, and (b) it can be #included directly in pcre_compile.c when that is compiled in debug mode. */ #ifdef SUPPORT_PCRE8 void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths); #endif #ifdef SUPPORT_PCRE16 void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths); #endif /* We need access to some of the data tables that PCRE uses. So as not to have to keep two copies, we include the source file here, changing the names of the external symbols to prevent clashes. */ #define PCRE_INCLUDED #include "pcre_tables.c" /* The definition of the macro PRINTABLE, which determines whether to print an output character as-is or as a hex value when showing compiled patterns, is the same as in the printint.src file. We uses it here in cases when the locale has not been explicitly changed, so as to get consistent output from systems that differ in their output from isprint() even in the "C" locale. */ #ifdef EBCDIC #define PRINTABLE(c) ((c) >= 64 && (c) < 255) #else #define PRINTABLE(c) ((c) >= 32 && (c) < 127) #endif #define PRINTOK(c) (locale_set? isprint(c) : PRINTABLE(c)) /* Posix support is disabled in 16 bit only mode. */ #if defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE8 && !defined NOPOSIX #define NOPOSIX #endif /* It is possible to compile this test program without including support for testing the POSIX interface, though this is not available via the standard Makefile. */ #if !defined NOPOSIX #include "pcreposix.h" #endif /* It is also possible, originally for the benefit of a version that was imported into Exim, to build pcretest without support for UTF8 or UTF16 (define NOUTF), without the interface to the DFA matcher (NODFA). In fact, we automatically cut out the UTF support if PCRE is built without it. */ #ifndef SUPPORT_UTF #ifndef NOUTF #define NOUTF #endif #endif /* To make the code a bit tidier for 8-bit and 16-bit support, we define macros for all the pcre[16]_xxx functions (except pcre16_fullinfo, which is called only from one place and is handled differently). I couldn't dream up any way of using a single macro to do this in a generic way, because of the many different argument requirements. We know that at least one of SUPPORT_PCRE8 and SUPPORT_PCRE16 must be set. First define macros for each individual mode; then use these in the definitions of generic macros. **** Special note about the PCHARSxxx macros: the address of the string to be printed is always given as two arguments: a base address followed by an offset. The base address is cast to the correct data size for 8 or 16 bit data; the offset is in units of this size. If the string were given as base+offset in one argument, the casting might be incorrectly applied. */ #ifdef SUPPORT_PCRE8 #define PCHARS8(lv, p, offset, len, f) \ lv = pchars((pcre_uint8 *)(p) + offset, len, f) #define PCHARSV8(p, offset, len, f) \ (void)pchars((pcre_uint8 *)(p) + offset, len, f) #define READ_CAPTURE_NAME8(p, cn8, cn16, re) \ p = read_capture_name8(p, cn8, re) #define STRLEN8(p) ((int)strlen((char *)p)) #define SET_PCRE_CALLOUT8(callout) \ pcre_callout = callout #define PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) \ pcre_assign_jit_stack(extra, callback, userdata) #define PCRE_COMPILE8(re, pat, options, error, erroffset, tables) \ re = pcre_compile((char *)pat, options, error, erroffset, tables) #define PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ namesptr, cbuffer, size) \ rc = pcre_copy_named_substring(re, (char *)bptr, offsets, count, \ (char *)namesptr, cbuffer, size) #define PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size) \ rc = pcre_copy_substring((char *)bptr, offsets, count, i, cbuffer, size) #define PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets, workspace, size_workspace) \ count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset, options, \ offsets, size_offsets, workspace, size_workspace) #define PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets) \ count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, \ offsets, size_offsets) #define PCRE_FREE_STUDY8(extra) \ pcre_free_study(extra) #define PCRE_FREE_SUBSTRING8(substring) \ pcre_free_substring(substring) #define PCRE_FREE_SUBSTRING_LIST8(listptr) \ pcre_free_substring_list(listptr) #define PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ getnamesptr, subsptr) \ rc = pcre_get_named_substring(re, (char *)bptr, offsets, count, \ (char *)getnamesptr, subsptr) #define PCRE_GET_STRINGNUMBER8(n, rc, ptr) \ n = pcre_get_stringnumber(re, (char *)ptr) #define PCRE_GET_SUBSTRING8(rc, bptr, offsets, count, i, subsptr) \ rc = pcre_get_substring((char *)bptr, offsets, count, i, subsptr) #define PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr) \ rc = pcre_get_substring_list((const char *)bptr, offsets, count, listptr) #define PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables) \ rc = pcre_pattern_to_host_byte_order(re, extra, tables) #define PCRE_PRINTINT8(re, outfile, debug_lengths) \ pcre_printint(re, outfile, debug_lengths) #define PCRE_STUDY8(extra, re, options, error) \ extra = pcre_study(re, options, error) #define PCRE_JIT_STACK_ALLOC8(startsize, maxsize) \ pcre_jit_stack_alloc(startsize, maxsize) #define PCRE_JIT_STACK_FREE8(stack) \ pcre_jit_stack_free(stack) #endif /* SUPPORT_PCRE8 */ /* -----------------------------------------------------------*/ #ifdef SUPPORT_PCRE16 #define PCHARS16(lv, p, offset, len, f) \ lv = pchars16((PCRE_SPTR16)(p) + offset, len, f) #define PCHARSV16(p, offset, len, f) \ (void)pchars16((PCRE_SPTR16)(p) + offset, len, f) #define READ_CAPTURE_NAME16(p, cn8, cn16, re) \ p = read_capture_name16(p, cn16, re) #define STRLEN16(p) ((int)strlen16((PCRE_SPTR16)p)) #define SET_PCRE_CALLOUT16(callout) \ pcre16_callout = (int (*)(pcre16_callout_block *))callout #define PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata) \ pcre16_assign_jit_stack((pcre16_extra *)extra, \ (pcre16_jit_callback)callback, userdata) #define PCRE_COMPILE16(re, pat, options, error, erroffset, tables) \ re = (pcre *)pcre16_compile((PCRE_SPTR16)pat, options, error, erroffset, \ tables) #define PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ namesptr, cbuffer, size) \ rc = pcre16_copy_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \ count, (PCRE_SPTR16)namesptr, (PCRE_UCHAR16 *)cbuffer, size/2) #define PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size) \ rc = pcre16_copy_substring((PCRE_SPTR16)bptr, offsets, count, i, \ (PCRE_UCHAR16 *)cbuffer, size/2) #define PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets, workspace, size_workspace) \ count = pcre16_dfa_exec((pcre16 *)re, (pcre16_extra *)extra, \ (PCRE_SPTR16)bptr, len, start_offset, options, offsets, size_offsets, \ workspace, size_workspace) #define PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets) \ count = pcre16_exec((pcre16 *)re, (pcre16_extra *)extra, (PCRE_SPTR16)bptr, \ len, start_offset, options, offsets, size_offsets) #define PCRE_FREE_STUDY16(extra) \ pcre16_free_study((pcre16_extra *)extra) #define PCRE_FREE_SUBSTRING16(substring) \ pcre16_free_substring((PCRE_SPTR16)substring) #define PCRE_FREE_SUBSTRING_LIST16(listptr) \ pcre16_free_substring_list((PCRE_SPTR16 *)listptr) #define PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ getnamesptr, subsptr) \ rc = pcre16_get_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \ count, (PCRE_SPTR16)getnamesptr, (PCRE_SPTR16 *)(void*)subsptr) #define PCRE_GET_STRINGNUMBER16(n, rc, ptr) \ n = pcre16_get_stringnumber(re, (PCRE_SPTR16)ptr) #define PCRE_GET_SUBSTRING16(rc, bptr, offsets, count, i, subsptr) \ rc = pcre16_get_substring((PCRE_SPTR16)bptr, offsets, count, i, \ (PCRE_SPTR16 *)(void*)subsptr) #define PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr) \ rc = pcre16_get_substring_list((PCRE_SPTR16)bptr, offsets, count, \ (PCRE_SPTR16 **)(void*)listptr) #define PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables) \ rc = pcre16_pattern_to_host_byte_order((pcre16 *)re, (pcre16_extra *)extra, \ tables) #define PCRE_PRINTINT16(re, outfile, debug_lengths) \ pcre16_printint(re, outfile, debug_lengths) #define PCRE_STUDY16(extra, re, options, error) \ extra = (pcre_extra *)pcre16_study((pcre16 *)re, options, error) #define PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \ (pcre_jit_stack *)pcre16_jit_stack_alloc(startsize, maxsize) #define PCRE_JIT_STACK_FREE16(stack) \ pcre16_jit_stack_free((pcre16_jit_stack *)stack) #endif /* SUPPORT_PCRE16 */ /* ----- Both modes are supported; a runtime test is needed, except for pcre_config(), and the JIT stack functions, when it doesn't matter which version is called. ----- */ #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 #define CHAR_SIZE (use_pcre16? 2:1) #define PCHARS(lv, p, offset, len, f) \ if (use_pcre16) \ PCHARS16(lv, p, offset, len, f); \ else \ PCHARS8(lv, p, offset, len, f) #define PCHARSV(p, offset, len, f) \ if (use_pcre16) \ PCHARSV16(p, offset, len, f); \ else \ PCHARSV8(p, offset, len, f) #define READ_CAPTURE_NAME(p, cn8, cn16, re) \ if (use_pcre16) \ READ_CAPTURE_NAME16(p, cn8, cn16, re); \ else \ READ_CAPTURE_NAME8(p, cn8, cn16, re) #define SET_PCRE_CALLOUT(callout) \ if (use_pcre16) \ SET_PCRE_CALLOUT16(callout); \ else \ SET_PCRE_CALLOUT8(callout) #define STRLEN(p) (use_pcre16? STRLEN16(p) : STRLEN8(p)) #define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \ if (use_pcre16) \ PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata); \ else \ PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \ if (use_pcre16) \ PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \ else \ PCRE_COMPILE8(re, pat, options, error, erroffset, tables) #define PCRE_CONFIG pcre_config #define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \ namesptr, cbuffer, size) \ if (use_pcre16) \ PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ namesptr, cbuffer, size); \ else \ PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ namesptr, cbuffer, size) #define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \ if (use_pcre16) \ PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size); \ else \ PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size) #define PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets, workspace, size_workspace) \ if (use_pcre16) \ PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets, workspace, size_workspace); \ else \ PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets, workspace, size_workspace) #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets) \ if (use_pcre16) \ PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets); \ else \ PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \ offsets, size_offsets) #define PCRE_FREE_STUDY(extra) \ if (use_pcre16) \ PCRE_FREE_STUDY16(extra); \ else \ PCRE_FREE_STUDY8(extra) #define PCRE_FREE_SUBSTRING(substring) \ if (use_pcre16) \ PCRE_FREE_SUBSTRING16(substring); \ else \ PCRE_FREE_SUBSTRING8(substring) #define PCRE_FREE_SUBSTRING_LIST(listptr) \ if (use_pcre16) \ PCRE_FREE_SUBSTRING_LIST16(listptr); \ else \ PCRE_FREE_SUBSTRING_LIST8(listptr) #define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \ getnamesptr, subsptr) \ if (use_pcre16) \ PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ getnamesptr, subsptr); \ else \ PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ getnamesptr, subsptr) #define PCRE_GET_STRINGNUMBER(n, rc, ptr) \ if (use_pcre16) \ PCRE_GET_STRINGNUMBER16(n, rc, ptr); \ else \ PCRE_GET_STRINGNUMBER8(n, rc, ptr) #define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \ if (use_pcre16) \ PCRE_GET_SUBSTRING16(rc, bptr, use_offsets, count, i, subsptr); \ else \ PCRE_GET_SUBSTRING8(rc, bptr, use_offsets, count, i, subsptr) #define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \ if (use_pcre16) \ PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr); \ else \ PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr) #define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \ (use_pcre16 ? \ PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \ :PCRE_JIT_STACK_ALLOC8(startsize, maxsize)) #define PCRE_JIT_STACK_FREE(stack) \ if (use_pcre16) \ PCRE_JIT_STACK_FREE16(stack); \ else \ PCRE_JIT_STACK_FREE8(stack) #define PCRE_MAKETABLES \ (use_pcre16? pcre16_maketables() : pcre_maketables()) #define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \ if (use_pcre16) \ PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables); \ else \ PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables) #define PCRE_PRINTINT(re, outfile, debug_lengths) \ if (use_pcre16) \ PCRE_PRINTINT16(re, outfile, debug_lengths); \ else \ PCRE_PRINTINT8(re, outfile, debug_lengths) #define PCRE_STUDY(extra, re, options, error) \ if (use_pcre16) \ PCRE_STUDY16(extra, re, options, error); \ else \ PCRE_STUDY8(extra, re, options, error) /* ----- Only 8-bit mode is supported ----- */ #elif defined SUPPORT_PCRE8 #define CHAR_SIZE 1 #define PCHARS PCHARS8 #define PCHARSV PCHARSV8 #define READ_CAPTURE_NAME READ_CAPTURE_NAME8 #define SET_PCRE_CALLOUT SET_PCRE_CALLOUT8 #define STRLEN STRLEN8 #define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK8 #define PCRE_COMPILE PCRE_COMPILE8 #define PCRE_CONFIG pcre_config #define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING8 #define PCRE_COPY_SUBSTRING PCRE_COPY_SUBSTRING8 #define PCRE_DFA_EXEC PCRE_DFA_EXEC8 #define PCRE_EXEC PCRE_EXEC8 #define PCRE_FREE_STUDY PCRE_FREE_STUDY8 #define PCRE_FREE_SUBSTRING PCRE_FREE_SUBSTRING8 #define PCRE_FREE_SUBSTRING_LIST PCRE_FREE_SUBSTRING_LIST8 #define PCRE_GET_NAMED_SUBSTRING PCRE_GET_NAMED_SUBSTRING8 #define PCRE_GET_STRINGNUMBER PCRE_GET_STRINGNUMBER8 #define PCRE_GET_SUBSTRING PCRE_GET_SUBSTRING8 #define PCRE_GET_SUBSTRING_LIST PCRE_GET_SUBSTRING_LIST8 #define PCRE_JIT_STACK_ALLOC PCRE_JIT_STACK_ALLOC8 #define PCRE_JIT_STACK_FREE PCRE_JIT_STACK_FREE8 #define PCRE_MAKETABLES pcre_maketables() #define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER8 #define PCRE_PRINTINT PCRE_PRINTINT8 #define PCRE_STUDY PCRE_STUDY8 /* ----- Only 16-bit mode is supported ----- */ #else #define CHAR_SIZE 2 #define PCHARS PCHARS16 #define PCHARSV PCHARSV16 #define READ_CAPTURE_NAME READ_CAPTURE_NAME16 #define SET_PCRE_CALLOUT SET_PCRE_CALLOUT16 #define STRLEN STRLEN16 #define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK16 #define PCRE_COMPILE PCRE_COMPILE16 #define PCRE_CONFIG pcre16_config #define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING16 #define PCRE_COPY_SUBSTRING PCRE_COPY_SUBSTRING16 #define PCRE_DFA_EXEC PCRE_DFA_EXEC16 #define PCRE_EXEC PCRE_EXEC16 #define PCRE_FREE_STUDY PCRE_FREE_STUDY16 #define PCRE_FREE_SUBSTRING PCRE_FREE_SUBSTRING16 #define PCRE_FREE_SUBSTRING_LIST PCRE_FREE_SUBSTRING_LIST16 #define PCRE_GET_NAMED_SUBSTRING PCRE_GET_NAMED_SUBSTRING16 #define PCRE_GET_STRINGNUMBER PCRE_GET_STRINGNUMBER16 #define PCRE_GET_SUBSTRING PCRE_GET_SUBSTRING16 #define PCRE_GET_SUBSTRING_LIST PCRE_GET_SUBSTRING_LIST16 #define PCRE_JIT_STACK_ALLOC PCRE_JIT_STACK_ALLOC16 #define PCRE_JIT_STACK_FREE PCRE_JIT_STACK_FREE16 #define PCRE_MAKETABLES pcre16_maketables() #define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER16 #define PCRE_PRINTINT PCRE_PRINTINT16 #define PCRE_STUDY PCRE_STUDY16 #endif /* ----- End of mode-specific function call macros ----- */ /* Other parameters */ #ifndef CLOCKS_PER_SEC #ifdef CLK_TCK #define CLOCKS_PER_SEC CLK_TCK #else #define CLOCKS_PER_SEC 100 #endif #endif #if !defined NODFA #define DFA_WS_DIMENSION 1000 #endif /* This is the default loop count for timing. */ #define LOOPREPEAT 500000 /* Static variables */ static FILE *outfile; static int log_store = 0; static int callout_count; static int callout_extra; static int callout_fail_count; static int callout_fail_id; static int debug_lengths; static int first_callout; static int jit_was_used; static int locale_set = 0; static int show_malloc; static int use_utf; static size_t gotten_store; static size_t first_gotten_store = 0; static const unsigned char *last_callout_mark = NULL; /* The buffers grow automatically if very long input lines are encountered. */ static int buffer_size = 50000; static pcre_uint8 *buffer = NULL; static pcre_uint8 *dbuffer = NULL; static pcre_uint8 *pbuffer = NULL; /* Another buffer is needed translation to 16-bit character strings. It will obtained and extended as required. */ #ifdef SUPPORT_PCRE16 static int buffer16_size = 0; static pcre_uint16 *buffer16 = NULL; #ifdef SUPPORT_PCRE8 /* We need the table of operator lengths that is used for 16-bit compiling, in order to swap bytes in a pattern for saving/reloading testing. Luckily, the data is defined as a macro. However, we must ensure that LINK_SIZE is adjusted appropriately for the 16-bit world. Just as a safety check, make sure that COMPILE_PCRE16 is *not* set. */ #ifdef COMPILE_PCRE16 #error COMPILE_PCRE16 must not be set when compiling pcretest.c #endif #if LINK_SIZE == 2 #undef LINK_SIZE #define LINK_SIZE 1 #elif LINK_SIZE == 3 || LINK_SIZE == 4 #undef LINK_SIZE #define LINK_SIZE 2 #else #error LINK_SIZE must be either 2, 3, or 4 #endif #undef IMM2_SIZE #define IMM2_SIZE 1 #endif /* SUPPORT_PCRE8 */ static const pcre_uint16 OP_lengths16[] = { OP_LENGTHS }; #endif /* SUPPORT_PCRE16 */ /* If we have 8-bit support, default use_pcre16 to false; if there is also 16-bit support, it can be changed by an option. If there is no 8-bit support, there must be 16-bit support, so default it to 1. */ #ifdef SUPPORT_PCRE8 static int use_pcre16 = 0; #else static int use_pcre16 = 1; #endif /* JIT study options for -s+n and /S+n where '1' <= n <= '7'. */ static int jit_study_bits[] = { PCRE_STUDY_JIT_COMPILE, PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE, PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE, PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE, PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE, PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE, PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE }; /* Textual explanations for runtime error codes */ static const char *errtexts[] = { NULL, /* 0 is no error */ NULL, /* NOMATCH is handled specially */ "NULL argument passed", "bad option value", "magic number missing", "unknown opcode - pattern overwritten?", "no more memory", NULL, /* never returned by pcre_exec() or pcre_dfa_exec() */ "match limit exceeded", "callout error code", NULL, /* BADUTF8/16 is handled specially */ NULL, /* BADUTF8/16 offset is handled specially */ NULL, /* PARTIAL is handled specially */ "not used - internal error", "internal error - pattern overwritten?", "bad count value", "item unsupported for DFA matching", "backreference condition or recursion test not supported for DFA matching", "match limit not supported for DFA matching", "workspace size exceeded in DFA matching", "too much recursion for DFA matching", "recursion limit exceeded", "not used - internal error", "invalid combination of newline options", "bad offset value", NULL, /* SHORTUTF8/16 is handled specially */ "nested recursion at the same subject position", "JIT stack limit reached", "pattern compiled in wrong mode: 8-bit/16-bit error", "pattern compiled with other endianness", "invalid data in workspace for DFA restart" }; /************************************************* * Alternate character tables * *************************************************/ /* By default, the "tables" pointer when calling PCRE is set to NULL, thereby using the default tables of the library. However, the T option can be used to select alternate sets of tables, for different kinds of testing. Note also that the L (locale) option also adjusts the tables. */ /* This is the set of tables distributed as default with PCRE. It recognizes only ASCII characters. */ static const pcre_uint8 tables0[] = { /* This table is a lower casing table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table is a case flipping table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table contains bit maps for various character classes. Each map is 32 bytes long and the bits run from the least significant end of each byte. The classes that have their own maps are: space, xdigit, digit, upper, lower, word, graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* This table identifies various classes of character by individual bits: 0x01 white space character 0x02 letter 0x04 decimal digit 0x08 hexadecimal digit 0x10 alphanumeric or '_' 0x80 regular expression metacharacter or binary zero */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ /* This is a set of tables that came orginally from a Windows user. It seems to be at least an approximation of ISO 8859. In particular, there are characters greater than 128 that are marked as spaces, letters, etc. */ static const pcre_uint8 tables1[] = { 0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, 24,25,26,27,28,29,30,31, 32,33,34,35,36,37,38,39, 40,41,42,43,44,45,46,47, 48,49,50,51,52,53,54,55, 56,57,58,59,60,61,62,63, 64,97,98,99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,91,92,93,94,95, 96,97,98,99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,215, 248,249,250,251,252,253,254,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, 0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, 24,25,26,27,28,29,30,31, 32,33,34,35,36,37,38,39, 40,41,42,43,44,45,46,47, 48,49,50,51,52,53,54,55, 56,57,58,59,60,61,62,63, 64,97,98,99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,91,92,93,94,95, 96,65,66,67,68,69,70,71, 72,73,74,75,76,77,78,79, 80,81,82,83,84,85,86,87, 88,89,90,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,215, 248,249,250,251,252,253,254,223, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,247, 216,217,218,219,220,221,222,255, 0,62,0,0,1,0,0,0, 0,0,0,0,0,0,0,0, 32,0,0,0,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,255,3, 126,0,0,0,126,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,255,3, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,12,2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 254,255,255,7,0,0,0,0, 0,0,0,0,0,0,0,0, 255,255,127,127,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,254,255,255,7, 0,0,0,0,0,4,32,4, 0,0,0,128,255,255,127,255, 0,0,0,0,0,0,255,3, 254,255,255,135,254,255,255,7, 0,0,0,0,0,4,44,6, 255,255,127,255,255,255,127,255, 0,0,0,0,254,255,255,255, 255,255,255,255,255,255,255,127, 0,0,0,0,254,255,255,255, 255,255,255,255,255,255,255,255, 0,2,0,0,255,255,255,255, 255,255,255,255,255,255,255,127, 0,0,0,0,255,255,255,255, 255,255,255,255,255,255,255,255, 0,0,0,0,254,255,0,252, 1,0,0,248,1,0,0,120, 0,0,0,0,254,255,255,255, 0,0,128,0,0,0,128,0, 255,255,255,255,0,0,0,0, 0,0,0,0,0,0,0,128, 255,255,255,255,0,0,0,0, 0,0,0,0,0,0,0,0, 128,0,0,0,0,0,0,0, 0,1,1,0,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,128,0,0,0, 128,128,128,128,0,0,128,0, 28,28,28,28,28,28,28,28, 28,28,0,0,0,0,0,128, 0,26,26,26,26,26,26,18, 18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18, 18,18,18,128,128,0,128,16, 0,26,26,26,26,26,26,18, 18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18, 18,18,18,128,128,0,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,0,18,0,0,0,0,0, 0,0,20,20,0,18,0,0, 0,20,18,0,0,0,0,0, 18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,0, 18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,0, 18,18,18,18,18,18,18,18 }; #ifndef HAVE_STRERROR /************************************************* * Provide strerror() for non-ANSI libraries * *************************************************/ /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() in their libraries, but can provide the same facility by this simple alternative function. */ extern int sys_nerr; extern char *sys_errlist[]; char * strerror(int n) { if (n < 0 || n >= sys_nerr) return "unknown error number"; return sys_errlist[n]; } #endif /* HAVE_STRERROR */ /************************************************* * JIT memory callback * *************************************************/ static pcre_jit_stack* jit_callback(void *arg) { jit_was_used = TRUE; return (pcre_jit_stack *)arg; } #if !defined NOUTF || defined SUPPORT_PCRE16 /************************************************* * Convert UTF-8 string to value * *************************************************/ /* This function takes one or more bytes that represents a UTF-8 character, and returns the value of the character. Argument: 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) */ static int utf82ord(pcre_uint8 *utf8bytes, int *vptr) { int c = *utf8bytes++; int d = c; int i, j, s; for (i = -1; i < 6; i++) /* i is number of additional bytes */ { if ((d & 0x80) == 0) break; d <<= 1; } if (i == -1) { *vptr = c; return 1; } /* ascii character */ if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ /* i now has a value in the range 1-5 */ s = 6*i; d = (c & utf8_table3[i]) << s; for (j = 0; j < i; j++) { c = *utf8bytes++; if ((c & 0xc0) != 0x80) return -(j+1); s -= 6; d |= (c & 0x3f) << s; } /* Check that encoding was the correct unique one */ for (j = 0; j < utf8_table1_size; j++) if (d <= utf8_table1[j]) break; if (j != i) return -(i+1); /* Valid value */ *vptr = d; return i+1; } #endif /* NOUTF || SUPPORT_PCRE16 */ #if !defined NOUTF || defined SUPPORT_PCRE16 /************************************************* * Convert character value to UTF-8 * *************************************************/ /* This function takes an integer value in the range 0 - 0x7fffffff and encodes it as a UTF-8 character in 0 to 6 bytes. Arguments: cvalue the character value utf8bytes pointer to buffer for result - at least 6 bytes long Returns: number of characters placed in the buffer */ static int ord2utf8(int cvalue, pcre_uint8 *utf8bytes) { register int i, j; for (i = 0; i < utf8_table1_size; i++) if (cvalue <= utf8_table1[i]) break; utf8bytes += i; for (j = i; j > 0; j--) { *utf8bytes-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } *utf8bytes = utf8_table2[i] | cvalue; return i + 1; } #endif #ifdef SUPPORT_PCRE16 /************************************************* * Convert a string to 16-bit * *************************************************/ /* In non-UTF mode, the space needed for a 16-bit string is exactly double the 8-bit size. For a UTF-8 string, the size needed for UTF-16 is no more than double, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4 in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-16. The result is always left in buffer16. Note that this function does not object to surrogate values. This is deliberate; it makes it possible to construct UTF-16 strings that are invalid, for the purpose of testing that they are correctly faulted. Patterns to be converted are either plain ASCII or UTF-8; data lines are always in UTF-8 so that values greater than 255 can be handled. Arguments: data TRUE if converting a data line; FALSE for a regex p points to a byte string utf true if UTF-8 (to be converted to UTF-16) len number of bytes in the string (excluding trailing zero) Returns: number of 16-bit data items used (excluding trailing zero) OR -1 if a UTF-8 string is malformed OR -2 if a value > 0x10ffff is encountered OR -3 if a value > 0xffff is encountered when not in UTF mode */ static int to16(int data, pcre_uint8 *p, int utf, int len) { pcre_uint16 *pp; if (buffer16_size < 2*len + 2) { if (buffer16 != NULL) free(buffer16); buffer16_size = 2*len + 2; buffer16 = (pcre_uint16 *)malloc(buffer16_size); if (buffer16 == NULL) { fprintf(stderr, "pcretest: malloc(%d) failed for buffer16\n", buffer16_size); exit(1); } } pp = buffer16; if (!utf && !data) { while (len-- > 0) *pp++ = *p++; } else { int c = 0; while (len > 0) { int chlen = utf82ord(p, &c); if (chlen <= 0) return -1; if (c > 0x10ffff) return -2; p += chlen; len -= chlen; if (c < 0x10000) *pp++ = c; else { if (!utf) return -3; c -= 0x10000; *pp++ = 0xD800 | (c >> 10); *pp++ = 0xDC00 | (c & 0x3ff); } } } *pp = 0; return pp - buffer16; } #endif /************************************************* * 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) prompt for stdin or readline() 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 pcre_uint8 * extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt) { pcre_uint8 *here = start; for (;;) { size_t rlen = (size_t)(buffer_size - (here - buffer)); if (rlen > 1000) { int dlen; /* If libreadline or libedit support is required, use readline() to read a line if the input is a terminal. Note that readline() removes the trailing newline, so we must put it back again, to be compatible with fgets(). */ #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) if (isatty(fileno(f))) { size_t len; char *s = readline(prompt); if (s == NULL) return (here == start)? NULL : start; len = strlen(s); if (len > 0) add_history(s); if (len > rlen - 1) len = rlen - 1; memcpy(here, s, len); here[len] = '\n'; here[len+1] = 0; free(s); } else #endif /* Read the next line by normal means, prompting if the file is stdin. */ { if (f == stdin) printf("%s", prompt); 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; pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size); pcre_uint8 *new_dbuffer = (pcre_uint8 *)malloc(new_buffer_size); pcre_uint8 *new_pbuffer = (pcre_uint8 *)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 * *************************************************/ /* We don't use strtoul() because SunOS4 doesn't have it. Rather than mess around with conditional compilation, just do the job by hand. It is only used for unpicking arguments, so just keep it simple. Arguments: str string to be converted endptr where to put the end pointer Returns: the unsigned long */ static int get_value(pcre_uint8 *str, pcre_uint8 **endptr) { int result = 0; while(*str != 0 && isspace(*str)) str++; while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0'); *endptr = str; return(result); } /************************************************* * Print one character * *************************************************/ /* Print a single character either literally, or as a hex escape. */ static int pchar(int c, FILE *f) { if (PRINTOK(c)) { if (f != NULL) fprintf(f, "%c", c); return 1; } if (c < 0x100) { if (use_utf) { if (f != NULL) fprintf(f, "\\x{%02x}", c); return 6; } else { if (f != NULL) fprintf(f, "\\x%02x", c); return 4; } } if (f != NULL) fprintf(f, "\\x{%02x}", c); return (c <= 0x000000ff)? 6 : (c <= 0x00000fff)? 7 : (c <= 0x0000ffff)? 8 : (c <= 0x000fffff)? 9 : 10; } #ifdef SUPPORT_PCRE8 /************************************************* * Print 8-bit character string * *************************************************/ /* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. If handed a NULL file, just counts chars without printing. */ static int pchars(pcre_uint8 *p, int length, FILE *f) { int c = 0; int yield = 0; if (length < 0) length = strlen((char *)p); while (length-- > 0) { #if !defined NOUTF if (use_utf) { int rc = utf82ord(p, &c); if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ { length -= rc - 1; p += rc; yield += pchar(c, f); continue; } } #endif c = *p++; yield += pchar(c, f); } return yield; } #endif #ifdef SUPPORT_PCRE16 /************************************************* * Find length of 0-terminated 16-bit string * *************************************************/ static int strlen16(PCRE_SPTR16 p) { int len = 0; while (*p++ != 0) len++; return len; } #endif /* SUPPORT_PCRE16 */ #ifdef SUPPORT_PCRE16 /************************************************* * Print 16-bit character string * *************************************************/ /* Must handle UTF-16 strings in utf mode. Yields number of characters printed. If handed a NULL file, just counts chars without printing. */ static int pchars16(PCRE_SPTR16 p, int length, FILE *f) { int yield = 0; if (length < 0) length = strlen16(p); while (length-- > 0) { int c = *p++ & 0xffff; #if !defined NOUTF if (use_utf && c >= 0xD800 && c < 0xDC00 && length > 0) { int d = *p & 0xffff; if (d >= 0xDC00 && d < 0xDFFF) { c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000; length--; p++; } } #endif yield += pchar(c, f); } return yield; } #endif /* SUPPORT_PCRE16 */ #ifdef SUPPORT_PCRE8 /************************************************* * Read a capture name (8-bit) and check it * *************************************************/ static pcre_uint8 * read_capture_name8(pcre_uint8 *p, pcre_uint8 **pp, pcre *re) { pcre_uint8 *npp = *pp; while (isalnum(*p)) *npp++ = *p++; *npp++ = 0; *npp = 0; if (pcre_get_stringnumber(re, (char *)(*pp)) < 0) { fprintf(outfile, "no parentheses with name \""); PCHARSV(*pp, 0, -1, outfile); fprintf(outfile, "\"\n"); } *pp = npp; return p; } #endif /* SUPPORT_PCRE8 */ #ifdef SUPPORT_PCRE16 /************************************************* * Read a capture name (16-bit) and check it * *************************************************/ /* Note that the text being read is 8-bit. */ static pcre_uint8 * read_capture_name16(pcre_uint8 *p, pcre_uint16 **pp, pcre *re) { pcre_uint16 *npp = *pp; while (isalnum(*p)) *npp++ = *p++; *npp++ = 0; *npp = 0; if (pcre16_get_stringnumber((pcre16 *)re, (PCRE_SPTR16)(*pp)) < 0) { fprintf(outfile, "no parentheses with name \""); PCHARSV(*pp, 0, -1, outfile); fprintf(outfile, "\"\n"); } *pp = npp; return p; } #endif /* SUPPORT_PCRE16 */ /************************************************* * Callout function * *************************************************/ /* Called from PCRE as a result of the (?C) item. We print out where we are in the match. Yield zero unless more callouts than the fail count, or the callout data is not zero. */ static int callout(pcre_callout_block *cb) { FILE *f = (first_callout | callout_extra)? outfile : NULL; int i, pre_start, post_start, subject_length; if (callout_extra) { fprintf(f, "Callout %d: last capture = %d\n", cb->callout_number, cb->capture_last); for (i = 0; i < cb->capture_top * 2; i += 2) { if (cb->offset_vector[i] < 0) fprintf(f, "%2d: \n", i/2); else { fprintf(f, "%2d: ", i/2); PCHARSV(cb->subject, cb->offset_vector[i], cb->offset_vector[i+1] - cb->offset_vector[i], f); fprintf(f, "\n"); } } } /* Re-print the subject in canonical form, the first time or if giving full datails. On subsequent calls in the same match, we use pchars just to find the printed lengths of the substrings. */ if (f != NULL) fprintf(f, "--->"); PCHARS(pre_start, cb->subject, 0, cb->start_match, f); PCHARS(post_start, cb->subject, cb->start_match, cb->current_position - cb->start_match, f); PCHARS(subject_length, cb->subject, 0, cb->subject_length, NULL); PCHARSV(cb->subject, cb->current_position, cb->subject_length - cb->current_position, f); if (f != NULL) fprintf(f, "\n"); /* Always print appropriate indicators, with callout number if not already shown. For automatic callouts, show the pattern offset. */ if (cb->callout_number == 255) { fprintf(outfile, "%+3d ", cb->pattern_position); if (cb->pattern_position > 99) fprintf(outfile, "\n "); } else { if (callout_extra) fprintf(outfile, " "); else fprintf(outfile, "%3d ", cb->callout_number); } for (i = 0; i < pre_start; i++) fprintf(outfile, " "); fprintf(outfile, "^"); if (post_start > 0) { for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); fprintf(outfile, "^"); } for (i = 0; i < subject_length - pre_start - post_start + 4; i++) fprintf(outfile, " "); fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length, pbuffer + cb->pattern_position); fprintf(outfile, "\n"); first_callout = 0; if (cb->mark != last_callout_mark) { if (cb->mark == NULL) fprintf(outfile, "Latest Mark: \n"); else { fprintf(outfile, "Latest Mark: "); PCHARSV(cb->mark, 0, -1, outfile); putc('\n', outfile); } last_callout_mark = cb->mark; } if (cb->callout_data != NULL) { int callout_data = *((int *)(cb->callout_data)); if (callout_data != 0) { fprintf(outfile, "Callout data = %d\n", callout_data); return callout_data; } } return (cb->callout_number != callout_fail_id)? 0 : (++callout_count >= callout_fail_count)? 1 : 0; } /************************************************* * Local malloc functions * *************************************************/ /* Alternative malloc function, to test functionality and save the size of a compiled re, which is the first store request that pcre_compile() makes. The show_malloc variable is set only during matching. */ static void *new_malloc(size_t size) { void *block = malloc(size); gotten_store = size; if (first_gotten_store == 0) first_gotten_store = size; if (show_malloc) fprintf(outfile, "malloc %3d %p\n", (int)size, block); return block; } static void new_free(void *block) { if (show_malloc) fprintf(outfile, "free %p\n", block); free(block); } /* For recursion malloc/free, to test stacking calls */ static void *stack_malloc(size_t size) { void *block = malloc(size); if (show_malloc) fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block); return block; } static void stack_free(void *block) { if (show_malloc) fprintf(outfile, "stack_free %p\n", block); free(block); } /************************************************* * Call pcre_fullinfo() * *************************************************/ /* Get one piece of information from the pcre_fullinfo() function. When only one of 8-bit or 16-bit is supported, use_pcre16 should always have the correct value, but the code is defensive. Arguments: re compiled regex study study data option PCRE_INFO_xxx option ptr where to put the data Returns: 0 when OK, < 0 on error */ static int new_info(pcre *re, pcre_extra *study, int option, void *ptr) { int rc; if (use_pcre16) #ifdef SUPPORT_PCRE16 rc = pcre16_fullinfo((pcre16 *)re, (pcre16_extra *)study, option, ptr); #else rc = PCRE_ERROR_BADMODE; #endif else #ifdef SUPPORT_PCRE8 rc = pcre_fullinfo(re, study, option, ptr); #else rc = PCRE_ERROR_BADMODE; #endif if (rc < 0) { fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc, use_pcre16? "16" : "", option); if (rc == PCRE_ERROR_BADMODE) fprintf(outfile, "Running in %s-bit mode but pattern was compiled in " "%s-bit mode\n", use_pcre16? "16":"8", use_pcre16? "8":"16"); } return rc; } /************************************************* * Swap byte functions * *************************************************/ /* The following functions swap the bytes of a pcre_uint16 and pcre_uint32 value, respectively. Arguments: value any number Returns: the byte swapped value */ static pcre_uint32 swap_uint32(pcre_uint32 value) { return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | (value >> 24); } static pcre_uint16 swap_uint16(pcre_uint16 value) { return (value >> 8) | (value << 8); } /************************************************* * Flip bytes in a compiled pattern * *************************************************/ /* This function is called if the 'F' option was present on a pattern that is to be written to a file. We flip the bytes of all the integer fields in the regex data block and the study block. In 16-bit mode this also flips relevant bytes in the pattern itself. This is to make it possible to test PCRE's ability to reload byte-flipped patterns, e.g. those compiled on a different architecture. */ static void regexflip(pcre *ere, pcre_extra *extra) { REAL_PCRE *re = (REAL_PCRE *)ere; #ifdef SUPPORT_PCRE16 int op; pcre_uint16 *ptr = (pcre_uint16 *)re + re->name_table_offset; int length = re->name_count * re->name_entry_size; #ifdef SUPPORT_UTF BOOL utf = (re->options & PCRE_UTF16) != 0; BOOL utf16_char = FALSE; #endif /* SUPPORT_UTF */ #endif /* SUPPORT_PCRE16 */ /* Always flip the bytes in the main data block and study blocks. */ re->magic_number = REVERSED_MAGIC_NUMBER; re->size = swap_uint32(re->size); re->options = swap_uint32(re->options); re->flags = swap_uint16(re->flags); re->top_bracket = swap_uint16(re->top_bracket); re->top_backref = swap_uint16(re->top_backref); re->first_char = swap_uint16(re->first_char); re->req_char = swap_uint16(re->req_char); re->name_table_offset = swap_uint16(re->name_table_offset); re->name_entry_size = swap_uint16(re->name_entry_size); re->name_count = swap_uint16(re->name_count); if (extra != NULL) { pcre_study_data *rsd = (pcre_study_data *)(extra->study_data); rsd->size = swap_uint32(rsd->size); rsd->flags = swap_uint32(rsd->flags); rsd->minlength = swap_uint32(rsd->minlength); } /* In 8-bit mode, that is all we need to do. In 16-bit mode we must swap bytes in the name table, if present, and then in the pattern itself. */ #ifdef SUPPORT_PCRE16 if (!use_pcre16) return; while(TRUE) { /* Swap previous characters. */ while (length-- > 0) { *ptr = swap_uint16(*ptr); ptr++; } #ifdef SUPPORT_UTF if (utf16_char) { if ((ptr[-1] & 0xfc00) == 0xd800) { /* We know that there is only one extra character in UTF-16. */ *ptr = swap_uint16(*ptr); ptr++; } } utf16_char = FALSE; #endif /* SUPPORT_UTF */ /* Get next opcode. */ length = 0; op = *ptr; *ptr++ = swap_uint16(op); switch (op) { case OP_END: return; #ifdef SUPPORT_UTF case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: case OP_UPTO: case OP_MINUPTO: case OP_EXACT: case OP_POSSTAR: case OP_POSPLUS: case OP_POSQUERY: case OP_POSUPTO: case OP_STARI: case OP_MINSTARI: case OP_PLUSI: case OP_MINPLUSI: case OP_QUERYI: case OP_MINQUERYI: case OP_UPTOI: case OP_MINUPTOI: case OP_EXACTI: case OP_POSSTARI: case OP_POSPLUSI: case OP_POSQUERYI: case OP_POSUPTOI: case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTEXACT: case OP_NOTPOSSTAR: case OP_NOTPOSPLUS: case OP_NOTPOSQUERY: case OP_NOTPOSUPTO: case OP_NOTSTARI: case OP_NOTMINSTARI: case OP_NOTPLUSI: case OP_NOTMINPLUSI: case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTUPTOI: case OP_NOTMINUPTOI: case OP_NOTEXACTI: case OP_NOTPOSSTARI: case OP_NOTPOSPLUSI: case OP_NOTPOSQUERYI: case OP_NOTPOSUPTOI: if (utf) utf16_char = TRUE; #endif /* Fall through. */ default: length = OP_lengths16[op] - 1; break; case OP_CLASS: case OP_NCLASS: /* Skip the character bit map. */ ptr += 32/sizeof(pcre_uint16); length = 0; break; case OP_XCLASS: /* LINK_SIZE can be 1 or 2 in 16 bit mode. */ if (LINK_SIZE > 1) length = (int)((((unsigned int)(ptr[0]) << 16) | (unsigned int)(ptr[1])) - (1 + LINK_SIZE + 1)); else length = (int)((unsigned int)(ptr[0]) - (1 + LINK_SIZE + 1)); /* Reverse the size of the XCLASS instance. */ *ptr = swap_uint16(*ptr); ptr++; if (LINK_SIZE > 1) { *ptr = swap_uint16(*ptr); ptr++; } op = *ptr; *ptr = swap_uint16(op); ptr++; if ((op & XCL_MAP) != 0) { /* Skip the character bit map. */ ptr += 32/sizeof(pcre_uint16); length -= 32/sizeof(pcre_uint16); } break; } } /* Control should never reach here in 16 bit mode. */ #endif /* SUPPORT_PCRE16 */ } /************************************************* * Check match or recursion limit * *************************************************/ static int check_match_limit(pcre *re, pcre_extra *extra, pcre_uint8 *bptr, int len, int start_offset, int options, int *use_offsets, int use_size_offsets, int flag, unsigned long int *limit, int errnumber, const char *msg) { int count; int min = 0; int mid = 64; int max = -1; extra->flags |= flag; for (;;) { *limit = mid; PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, use_offsets, use_size_offsets); if (count == errnumber) { /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ min = mid; mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2; } else if (count >= 0 || count == PCRE_ERROR_NOMATCH || count == PCRE_ERROR_PARTIAL) { if (mid == min + 1) { fprintf(outfile, "Minimum %s limit = %d\n", msg, mid); break; } /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ max = mid; mid = (min + mid)/2; } else break; /* Some other error */ } extra->flags &= ~flag; return count; } /************************************************* * Case-independent strncmp() function * *************************************************/ /* Arguments: s first string t second string n number of characters to compare Returns: < 0, = 0, or > 0, according to the comparison */ static int strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n) { while (n--) { int c = tolower(*s++) - tolower(*t++); if (c) return c; } return 0; } /************************************************* * Check newline indicator * *************************************************/ /* This is used both at compile and run-time to check for escapes. 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(pcre_uint8 *p, FILE *f) { if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR; if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF; if (strncmpic(p, (pcre_uint8 *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF; if (strncmpic(p, (pcre_uint8 *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF; if (strncmpic(p, (pcre_uint8 *)"any>", 4) == 0) return PCRE_NEWLINE_ANY; if (strncmpic(p, (pcre_uint8 *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF; if (strncmpic(p, (pcre_uint8 *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE; fprintf(f, "Unknown newline type at: <%s\n", p); return 0; } /************************************************* * Usage function * *************************************************/ static void usage(void) { printf("Usage: pcretest [options] [ []]\n\n"); printf("Input and output default to stdin and stdout.\n"); #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) printf("If input is a terminal, readline() is used to read from it.\n"); #else printf("This version of pcretest is not linked with readline().\n"); #endif printf("\nOptions:\n"); #ifdef SUPPORT_PCRE16 printf(" -16 use the 16-bit library\n"); #endif printf(" -b show compiled code\n"); printf(" -C show PCRE compile-time options and exit\n"); printf(" -C arg show a specific compile-time option\n"); printf(" and exit with its value. The arg can be:\n"); printf(" linksize internal link size [2, 3, 4]\n"); printf(" pcre8 8 bit library support enabled [0, 1]\n"); printf(" pcre16 16 bit library support enabled [0, 1]\n"); printf(" utf Unicode Transformation Format supported [0, 1]\n"); printf(" ucp Unicode Properties supported [0, 1]\n"); printf(" jit Just-in-time compiler supported [0, 1]\n"); printf(" newline Newline type [CR, LF, CRLF, ANYCRLF, ANY, ???]\n"); printf(" -d debug: show compiled code and information (-b and -i)\n"); #if !defined NODFA printf(" -dfa force DFA matching for all subjects\n"); #endif printf(" -help show usage information\n"); printf(" -i show information about compiled patterns\n" " -M find MATCH_LIMIT minimum for each subject\n" " -m output memory used information\n" " -o set size of offsets vector to \n"); #if !defined NOPOSIX printf(" -p use POSIX interface\n"); #endif printf(" -q quiet: do not output PCRE version number at start\n"); printf(" -S set stack size to megabytes\n"); printf(" -s force each pattern to be studied at basic level\n" " -s+ force each pattern to be studied, using JIT if available\n" " -s++ ditto, verifying when JIT was actually used\n" " -s+n force each pattern to be studied, using JIT if available,\n" " where 1 <= n <= 7 selects JIT options\n" " -s++n ditto, verifying when JIT was actually used\n" " -t time compilation and execution\n"); printf(" -t time compilation and execution, repeating times\n"); printf(" -tm time execution (matching) only\n"); printf(" -tm time execution (matching) only, repeating times\n"); } /************************************************* * Main Program * *************************************************/ /* Read lines from named file or stdin and write to named file or stdout; lines consist of a regular expression, in delimiters and optionally followed by options, followed by a set of test data, terminated by an empty line. */ int main(int argc, char **argv) { FILE *infile = stdin; const char *version; int options = 0; int study_options = 0; int default_find_match_limit = FALSE; int op = 1; int timeit = 0; int timeitm = 0; int showinfo = 0; int showstore = 0; int force_study = -1; int force_study_options = 0; int quiet = 0; int size_offsets = 45; int size_offsets_max; int *offsets = NULL; int debug = 0; int done = 0; int all_use_dfa = 0; int verify_jit = 0; int yield = 0; int stack_size; #if !defined NOPOSIX int posix = 0; #endif #if !defined NODFA int *dfa_workspace = NULL; #endif pcre_jit_stack *jit_stack = NULL; /* These vectors store, end-to-end, a list of zero-terminated captured substring names, each list itself being terminated by an empty name. Assume that 1024 is plenty long enough for the few names we'll be testing. It is easiest to keep separate 8-bit and 16-bit versions, using the 16-bit version for the actual memory, to ensure alignment. */ pcre_uint16 copynames[1024]; pcre_uint16 getnames[1024]; #ifdef SUPPORT_PCRE16 pcre_uint16 *cn16ptr; pcre_uint16 *gn16ptr; #endif #ifdef SUPPORT_PCRE8 pcre_uint8 *copynames8 = (pcre_uint8 *)copynames; pcre_uint8 *getnames8 = (pcre_uint8 *)getnames; pcre_uint8 *cn8ptr; pcre_uint8 *gn8ptr; #endif /* Get buffers from malloc() so that valgrind will check their misuse when debugging. They grow automatically when very long lines are read. The 16-bit buffer (buffer16) is obtained only if needed. */ buffer = (pcre_uint8 *)malloc(buffer_size); dbuffer = (pcre_uint8 *)malloc(buffer_size); pbuffer = (pcre_uint8 *)malloc(buffer_size); /* The outfile variable is static so that new_malloc can use it. */ outfile = stdout; /* The following _setmode() stuff is some Windows magic that tells its runtime library to translate CRLF into a single LF character. At least, that's what I've been told: never having used Windows I take this all on trust. Originally it set 0x8000, but then I was advised that _O_BINARY was better. */ #if defined(_WIN32) || defined(WIN32) _setmode( _fileno( stdout ), _O_BINARY ); #endif /* Get the version number: both pcre_version() and pcre16_version() give the same answer. We just need to ensure that we call one that is available. */ #ifdef SUPPORT_PCRE8 version = pcre_version(); #else version = pcre16_version(); #endif /* Scan options */ while (argc > 1 && argv[op][0] == '-') { pcre_uint8 *endptr; char *arg = argv[op]; if (strcmp(arg, "-m") == 0) showstore = 1; else if (strcmp(arg, "-s") == 0) force_study = 0; else if (strncmp(arg, "-s+", 3) == 0) { arg += 3; if (*arg == '+') { arg++; verify_jit = TRUE; } force_study = 1; if (*arg == 0) force_study_options = jit_study_bits[6]; else if (*arg >= '1' && *arg <= '7') force_study_options = jit_study_bits[*arg - '1']; else goto BAD_ARG; } else if (strcmp(arg, "-16") == 0) { #ifdef SUPPORT_PCRE16 use_pcre16 = 1; #else printf("** This version of PCRE was built without 16-bit support\n"); exit(1); #endif } else if (strcmp(arg, "-q") == 0) quiet = 1; else if (strcmp(arg, "-b") == 0) debug = 1; else if (strcmp(arg, "-i") == 0) showinfo = 1; else if (strcmp(arg, "-d") == 0) showinfo = debug = 1; else if (strcmp(arg, "-M") == 0) default_find_match_limit = TRUE; #if !defined NODFA else if (strcmp(arg, "-dfa") == 0) all_use_dfa = 1; #endif else if (strcmp(arg, "-o") == 0 && argc > 2 && ((size_offsets = get_value((pcre_uint8 *)argv[op+1], &endptr)), *endptr == 0)) { op++; argc--; } else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0) { int both = arg[2] == 0; int temp; if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr), *endptr == 0)) { timeitm = temp; op++; argc--; } else timeitm = LOOPREPEAT; if (both) timeit = timeitm; } else if (strcmp(arg, "-S") == 0 && argc > 2 && ((stack_size = get_value((pcre_uint8 *)argv[op+1], &endptr)), *endptr == 0)) { #if defined(_WIN32) || defined(WIN32) || defined(__minix) 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(arg, "-p") == 0) posix = 1; #endif else if (strcmp(arg, "-C") == 0) { int rc; unsigned long int lrc; if (argc > 2) { if (strcmp(argv[op + 1], "linksize") == 0) { (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc); printf("%d\n", rc); yield = rc; goto EXIT; } if (strcmp(argv[op + 1], "pcre8") == 0) { #ifdef SUPPORT_PCRE8 printf("1\n"); yield = 1; #else printf("0\n"); yield = 0; #endif goto EXIT; } if (strcmp(argv[op + 1], "pcre16") == 0) { #ifdef SUPPORT_PCRE16 printf("1\n"); yield = 1; #else printf("0\n"); yield = 0; #endif goto EXIT; } if (strcmp(argv[op + 1], "utf") == 0) { #ifdef SUPPORT_PCRE8 (void)pcre_config(PCRE_CONFIG_UTF8, &rc); printf("%d\n", rc); yield = rc; #else (void)pcre16_config(PCRE_CONFIG_UTF16, &rc); printf("%d\n", rc); yield = rc; #endif goto EXIT; } if (strcmp(argv[op + 1], "ucp") == 0) { (void)PCRE_CONFIG(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); printf("%d\n", rc); yield = rc; goto EXIT; } if (strcmp(argv[op + 1], "jit") == 0) { (void)PCRE_CONFIG(PCRE_CONFIG_JIT, &rc); printf("%d\n", rc); yield = rc; goto EXIT; } if (strcmp(argv[op + 1], "newline") == 0) { (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc); /* Note that these values are always the ASCII values, even in EBCDIC environments. CR is 13 and NL is 10. */ printf("%s\n", (rc == 13)? "CR" : (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" : (rc == -2)? "ANYCRLF" : (rc == -1)? "ANY" : "???"); goto EXIT; } printf("Unknown -C option: %s\n", argv[op + 1]); goto EXIT; } printf("PCRE version %s\n", version); printf("Compiled with\n"); /* At least one of SUPPORT_PCRE8 and SUPPORT_PCRE16 will be set. If both are set, either both UTFs are supported or both are not supported. */ #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 printf(" 8-bit and 16-bit support\n"); (void)pcre_config(PCRE_CONFIG_UTF8, &rc); if (rc) printf(" UTF-8 and UTF-16 support\n"); else printf(" No UTF-8 or UTF-16 support\n"); #elif defined SUPPORT_PCRE8 printf(" 8-bit support only\n"); (void)pcre_config(PCRE_CONFIG_UTF8, &rc); printf(" %sUTF-8 support\n", rc? "" : "No "); #else printf(" 16-bit support only\n"); (void)pcre16_config(PCRE_CONFIG_UTF16, &rc); printf(" %sUTF-16 support\n", rc? "" : "No "); #endif (void)PCRE_CONFIG(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); printf(" %sUnicode properties support\n", rc? "" : "No "); (void)PCRE_CONFIG(PCRE_CONFIG_JIT, &rc); if (rc) { const char *arch; (void)PCRE_CONFIG(PCRE_CONFIG_JITTARGET, (void *)(&arch)); printf(" Just-in-time compiler support: %s\n", arch); } else printf(" No just-in-time compiler support\n"); (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc); /* Note that these values are always the ASCII values, even in EBCDIC environments. CR is 13 and NL is 10. */ printf(" Newline sequence is %s\n", (rc == 13)? "CR" : (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" : (rc == -2)? "ANYCRLF" : (rc == -1)? "ANY" : "???"); (void)PCRE_CONFIG(PCRE_CONFIG_BSR, &rc); printf(" \\R matches %s\n", rc? "CR, LF, or CRLF only" : "all Unicode newlines"); (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc); printf(" Internal link size = %d\n", rc); (void)PCRE_CONFIG(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); printf(" POSIX malloc threshold = %d\n", rc); (void)PCRE_CONFIG(PCRE_CONFIG_MATCH_LIMIT, &lrc); printf(" Default match limit = %ld\n", lrc); (void)PCRE_CONFIG(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc); printf(" Default recursion depth limit = %ld\n", lrc); (void)PCRE_CONFIG(PCRE_CONFIG_STACKRECURSE, &rc); printf(" Match recursion uses %s", rc? "stack" : "heap"); if (showstore) { PCRE_EXEC(stack_size, NULL, NULL, NULL, -999, -999, 0, NULL, 0); printf(": %sframe size = %d bytes", rc? "approximate " : "", -stack_size); } printf("\n"); goto EXIT; } else if (strcmp(arg, "-help") == 0 || strcmp(arg, "--help") == 0) { usage(); goto EXIT; } else { BAD_ARG: printf("** Unknown or malformed option %s\n", arg); usage(); yield = 1; goto EXIT; } op++; argc--; } /* Get the store for the offsets vector, and remember what it was */ size_offsets_max = size_offsets; offsets = (int *)malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", (int)(size_offsets_max * sizeof(int))); yield = 1; goto EXIT; } /* Sort out the input and output files */ if (argc > 1) { infile = fopen(argv[op], INPUT_MODE); if (infile == NULL) { printf("** Failed to open %s\n", argv[op]); yield = 1; goto EXIT; } } if (argc > 2) { outfile = fopen(argv[op+1], OUTPUT_MODE); if (outfile == NULL) { printf("** Failed to open %s\n", argv[op+1]); yield = 1; goto EXIT; } } /* Set alternative malloc function */ #ifdef SUPPORT_PCRE8 pcre_malloc = new_malloc; pcre_free = new_free; pcre_stack_malloc = stack_malloc; pcre_stack_free = stack_free; #endif #ifdef SUPPORT_PCRE16 pcre16_malloc = new_malloc; pcre16_free = new_free; pcre16_stack_malloc = stack_malloc; pcre16_stack_free = stack_free; #endif /* Heading line unless quiet, then prompt for first regex if stdin */ if (!quiet) fprintf(outfile, "PCRE version %s\n\n", version); /* Main loop */ while (!done) { pcre *re = NULL; pcre_extra *extra = NULL; #if !defined NOPOSIX /* There are still compilers that require no indent */ regex_t preg; int do_posix = 0; #endif const char *error; pcre_uint8 *markptr; pcre_uint8 *p, *pp, *ppp; pcre_uint8 *to_file = NULL; const pcre_uint8 *tables = NULL; unsigned long int get_options; unsigned long int true_size, true_study_size = 0; size_t size, regex_gotten_store; int do_allcaps = 0; int do_mark = 0; int do_study = 0; int no_force_study = 0; int do_debug = debug; int do_G = 0; int do_g = 0; int do_showinfo = showinfo; int do_showrest = 0; int do_showcaprest = 0; int do_flip = 0; int erroroffset, len, delimiter, poffset; #if !defined NODFA int dfa_matched = 0; #endif use_utf = 0; debug_lengths = 1; if (extend_inputline(infile, buffer, " re> ") == NULL) break; if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); fflush(outfile); p = buffer; while (isspace(*p)) p++; if (*p == 0) continue; /* See if the pattern is to be loaded pre-compiled from a file. */ if (*p == '<' && strchr((char *)(p+1), '<') == NULL) { pcre_uint32 magic; pcre_uint8 sbuf[8]; FILE *f; p++; if (*p == '!') { do_debug = TRUE; do_showinfo = TRUE; p++; } pp = p + (int)strlen((char *)p); while (isspace(pp[-1])) pp--; *pp = 0; f = fopen((char *)p, "rb"); if (f == NULL) { fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno)); continue; } first_gotten_store = 0; if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; true_size = (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3]; true_study_size = (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7]; re = (pcre *)new_malloc(true_size); regex_gotten_store = first_gotten_store; if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; magic = ((REAL_PCRE *)re)->magic_number; if (magic != MAGIC_NUMBER) { if (swap_uint32(magic) == MAGIC_NUMBER) { do_flip = 1; } else { fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p); fclose(f); continue; } } /* We hide the byte-invert info for little and big endian tests. */ fprintf(outfile, "Compiled pattern%s loaded from %s\n", do_flip && (p[-1] == '<') ? " (byte-inverted)" : "", p); /* Now see if there is any following study data. */ if (true_study_size != 0) { pcre_study_data *psd; extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size); extra->flags = PCRE_EXTRA_STUDY_DATA; psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra)); extra->study_data = psd; if (fread(psd, 1, true_study_size, f) != true_study_size) { FAIL_READ: fprintf(outfile, "Failed to read data from %s\n", p); if (extra != NULL) { PCRE_FREE_STUDY(extra); } if (re != NULL) new_free(re); fclose(f); continue; } fprintf(outfile, "Study data loaded from %s\n", p); do_study = 1; /* To get the data output if requested */ } else fprintf(outfile, "No study data\n"); /* Flip the necessary bytes. */ if (do_flip) { int rc; PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, NULL); if (rc == PCRE_ERROR_BADMODE) { /* Simulate the result of the function call below. */ fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc, use_pcre16? "16" : "", PCRE_INFO_OPTIONS); fprintf(outfile, "Running in %s-bit mode but pattern was compiled in " "%s-bit mode\n", use_pcre16? "16":"8", use_pcre16? "8":"16"); continue; } } /* Need to know if UTF-8 for printing data strings. */ if (new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options) < 0) continue; use_utf = (get_options & PCRE_UTF8) != 0; fclose(f); goto SHOW_INFO; } /* In-line pattern (the usual case). Get the delimiter and seek the end of the pattern; if it isn't complete, read more. */ delimiter = *p++; if (isalnum(delimiter) || delimiter == '\\') { fprintf(outfile, "** Delimiter must not be alphanumeric or \\\n"); goto SKIP_DATA; } pp = p; poffset = (int)(p - buffer); for(;;) { while (*pp != 0) { if (*pp == '\\' && pp[1] != 0) pp++; else if (*pp == delimiter) break; pp++; } if (*pp != 0) break; if ((pp = extend_inputline(infile, pp, " > ")) == NULL) { fprintf(outfile, "** Unexpected EOF\n"); done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)pp); } /* The buffer may have moved while being extended; reset the start of data pointer to the correct relative point in the buffer. */ p = buffer + poffset; /* If the first character after the delimiter is backslash, make the pattern end with backslash. This is purely to provide a way of testing for the error message when a pattern ends with backslash. */ if (pp[1] == '\\') *pp++ = '\\'; /* Terminate the pattern at the delimiter, and save a copy of the pattern for callouts. */ *pp++ = 0; strcpy((char *)pbuffer, (char *)p); /* Look for options after final delimiter */ options = 0; study_options = 0; log_store = showstore; /* default from command line */ while (*pp != 0) { switch (*pp++) { case 'f': options |= PCRE_FIRSTLINE; break; case 'g': do_g = 1; break; case 'i': options |= PCRE_CASELESS; break; case 'm': options |= PCRE_MULTILINE; break; case 's': options |= PCRE_DOTALL; break; case 'x': options |= PCRE_EXTENDED; break; case '+': if (do_showrest) do_showcaprest = 1; else do_showrest = 1; break; case '=': do_allcaps = 1; break; case 'A': options |= PCRE_ANCHORED; break; case 'B': do_debug = 1; break; case 'C': options |= PCRE_AUTO_CALLOUT; break; case 'D': do_debug = do_showinfo = 1; break; case 'E': options |= PCRE_DOLLAR_ENDONLY; break; 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 'K': do_mark = 1; break; case 'M': log_store = 1; break; case 'N': options |= PCRE_NO_AUTO_CAPTURE; break; #if !defined NOPOSIX case 'P': do_posix = 1; break; #endif case 'S': if (do_study == 0) { do_study = 1; if (*pp == '+') { if (*(++pp) == '+') { verify_jit = TRUE; pp++; } if (*pp >= '1' && *pp <= '7') study_options |= jit_study_bits[*pp++ - '1']; else study_options |= jit_study_bits[6]; } } else { do_study = 0; no_force_study = 1; } break; case 'U': options |= PCRE_UNGREEDY; break; case 'W': options |= PCRE_UCP; break; case 'X': options |= PCRE_EXTRA; break; case 'Y': options |= PCRE_NO_START_OPTIMISE; break; case 'Z': debug_lengths = 0; break; case '8': options |= PCRE_UTF8; use_utf = 1; break; case '?': options |= PCRE_NO_UTF8_CHECK; break; case 'T': switch (*pp++) { case '0': tables = tables0; break; case '1': tables = tables1; break; case '\r': case '\n': case ' ': case 0: fprintf(outfile, "** Missing table number after /T\n"); goto SKIP_DATA; default: fprintf(outfile, "** Bad table number \"%c\" after /T\n", pp[-1]); goto SKIP_DATA; } break; case 'L': ppp = pp; /* The '\r' test here is so that it works on Windows. */ /* The '0' test is just in case this is an unterminated line. */ while (*ppp != 0 && *ppp != '\n' && *ppp != '\r' && *ppp != ' ') ppp++; *ppp = 0; if (setlocale(LC_CTYPE, (const char *)pp) == NULL) { fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); goto SKIP_DATA; } locale_set = 1; tables = PCRE_MAKETABLES; pp = ppp; break; case '>': to_file = pp; while (*pp != 0) pp++; while (isspace(pp[-1])) pp--; *pp = 0; break; case '<': { if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0) { options |= PCRE_JAVASCRIPT_COMPAT; pp += 3; } else { 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 ' ': break; default: fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); goto SKIP_DATA; } } /* Handle compiling via the POSIX interface, which doesn't support the timing, showing, or debugging options, nor the ability to pass over local character tables. Neither does it have 16-bit support. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int cflags = 0; if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL; if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB; if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8; if ((options & PCRE_UCP) != 0) cflags |= REG_UCP; if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY; first_gotten_store = 0; rc = regcomp(&preg, (char *)p, cflags); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, buffer_size); fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); goto SKIP_DATA; } } /* Handle compiling via the native interface */ else #endif /* !defined NOPOSIX */ { /* In 16-bit mode, convert the input. */ #ifdef SUPPORT_PCRE16 if (use_pcre16) { switch(to16(FALSE, p, options & PCRE_UTF8, (int)strlen((char *)p))) { case -1: fprintf(outfile, "**Failed: invalid UTF-8 string cannot be " "converted to UTF-16\n"); goto SKIP_DATA; case -2: fprintf(outfile, "**Failed: character value greater than 0x10ffff " "cannot be converted to UTF-16\n"); goto SKIP_DATA; case -3: /* "Impossible error" when to16 is called arg1 FALSE */ fprintf(outfile, "**Failed: character value greater than 0xffff " "cannot be converted to 16-bit in non-UTF mode\n"); goto SKIP_DATA; default: break; } p = (pcre_uint8 *)buffer16; } #endif /* Compile many times when timing */ if (timeit > 0) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < timeit; i++) { PCRE_COMPILE(re, p, options, &error, &erroroffset, tables); if (re != NULL) free(re); } time_taken = clock() - start_time; fprintf(outfile, "Compile time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeit) / (double)CLOCKS_PER_SEC); } first_gotten_store = 0; PCRE_COMPILE(re, p, options, &error, &erroroffset, tables); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (re == NULL) { fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); SKIP_DATA: if (infile != stdin) { for (;;) { if (extend_inputline(infile, buffer, NULL) == NULL) { done = 1; goto CONTINUE; } len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; if (len == 0) break; } fprintf(outfile, "\n"); } goto CONTINUE; } /* Compilation succeeded. It is now possible to set the UTF-8 option from within the regex; check for this so that we know how to process the data lines. */ if (new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options) < 0) goto SKIP_DATA; if ((get_options & PCRE_UTF8) != 0) use_utf = 1; /* Extract the size for possible writing before possibly flipping it, and remember the store that was got. */ true_size = ((REAL_PCRE *)re)->size; regex_gotten_store = first_gotten_store; /* Output code size information if requested */ if (log_store) fprintf(outfile, "Memory allocation (code space): %d\n", (int)(first_gotten_store - sizeof(REAL_PCRE) - ((REAL_PCRE *)re)->name_count * ((REAL_PCRE *)re)->name_entry_size)); /* If -s or /S was present, study the regex to generate additional info to help with the matching, unless the pattern has the SS option, which suppresses the effect of /S (used for a few test patterns where studying is never sensible). */ if (do_study || (force_study >= 0 && !no_force_study)) { if (timeit > 0) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < timeit; i++) { PCRE_STUDY(extra, re, study_options | force_study_options, &error); } time_taken = clock() - start_time; if (extra != NULL) { PCRE_FREE_STUDY(extra); } fprintf(outfile, " Study time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeit) / (double)CLOCKS_PER_SEC); } PCRE_STUDY(extra, re, study_options | force_study_options, &error); if (error != NULL) fprintf(outfile, "Failed to study: %s\n", error); else if (extra != NULL) { true_study_size = ((pcre_study_data *)(extra->study_data))->size; if (log_store) { size_t jitsize; if (new_info(re, extra, PCRE_INFO_JITSIZE, &jitsize) == 0 && jitsize != 0) fprintf(outfile, "Memory allocation (JIT code): %d\n", (int)jitsize); } } } /* If /K was present, we set up for handling MARK data. */ if (do_mark) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->mark = &markptr; extra->flags |= PCRE_EXTRA_MARK; } /* Extract and display information from the compiled data if required. */ SHOW_INFO: if (do_debug) { fprintf(outfile, "------------------------------------------------------------------\n"); PCRE_PRINTINT(re, outfile, debug_lengths); } /* We already have the options in get_options (see above) */ if (do_showinfo) { unsigned long int all_options; int count, backrefmax, first_char, need_char, okpartial, jchanged, hascrorlf, maxlookbehind; int nameentrysize, namecount; const pcre_uint8 *nametable; if (new_info(re, NULL, PCRE_INFO_SIZE, &size) + new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count) + new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax) + new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char) + new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char) + new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize) + new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount) + new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable) + new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial) + new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged) + new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf) + new_info(re, NULL, PCRE_INFO_MAXLOOKBEHIND, &maxlookbehind) != 0) goto SKIP_DATA; if (size != regex_gotten_store) fprintf(outfile, "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", (int)size, (int)regex_gotten_store); fprintf(outfile, "Capturing subpattern count = %d\n", count); if (backrefmax > 0) fprintf(outfile, "Max back reference = %d\n", backrefmax); if (namecount > 0) { fprintf(outfile, "Named capturing subpatterns:\n"); while (namecount-- > 0) { #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 int imm2_size = use_pcre16 ? 1 : 2; #else int imm2_size = IMM2_SIZE; #endif int length = (int)STRLEN(nametable + imm2_size); fprintf(outfile, " "); PCHARSV(nametable, imm2_size, length, outfile); while (length++ < nameentrysize - imm2_size) putc(' ', outfile); #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 fprintf(outfile, "%3d\n", use_pcre16? (int)(((PCRE_SPTR16)nametable)[0]) :((int)nametable[0] << 8) | (int)nametable[1]); nametable += nameentrysize * (use_pcre16 ? 2 : 1); #else fprintf(outfile, "%3d\n", GET2(nametable, 0)); #ifdef SUPPORT_PCRE8 nametable += nameentrysize; #else nametable += nameentrysize * 2; #endif #endif } } if (!okpartial) fprintf(outfile, "Partial matching not supported\n"); if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); all_options = ((REAL_PCRE *)re)->options; if (do_flip) all_options = swap_uint32(all_options); 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%s%s%s%s%s\n", ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "", ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", ((get_options & PCRE_BSR_ANYCRLF) != 0)? " bsr_anycrlf" : "", ((get_options & PCRE_BSR_UNICODE) != 0)? " bsr_unicode" : "", ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", ((get_options & PCRE_EXTRA) != 0)? " extra" : "", ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "", ((get_options & PCRE_UTF8) != 0)? " utf" : "", ((get_options & PCRE_UCP) != 0)? " ucp" : "", ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf_check" : "", ((get_options & PCRE_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "", ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : ""); if (jchanged) fprintf(outfile, "Duplicate name status changes\n"); switch (get_options & PCRE_NEWLINE_BITS) { case PCRE_NEWLINE_CR: fprintf(outfile, "Forced newline sequence: CR\n"); break; case PCRE_NEWLINE_LF: fprintf(outfile, "Forced newline sequence: LF\n"); break; case PCRE_NEWLINE_CRLF: fprintf(outfile, "Forced newline sequence: CRLF\n"); break; case PCRE_NEWLINE_ANYCRLF: fprintf(outfile, "Forced newline sequence: ANYCRLF\n"); break; case PCRE_NEWLINE_ANY: fprintf(outfile, "Forced newline sequence: ANY\n"); break; default: break; } if (first_char == -1) { fprintf(outfile, "First char at start or follows newline\n"); } else if (first_char < 0) { fprintf(outfile, "No first char\n"); } else { const char *caseless = ((((REAL_PCRE *)re)->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)"; if (PRINTOK(first_char)) fprintf(outfile, "First char = \'%c\'%s\n", first_char, caseless); else { fprintf(outfile, "First char = "); pchar(first_char, outfile); fprintf(outfile, "%s\n", caseless); } } if (need_char < 0) { fprintf(outfile, "No need char\n"); } else { const char *caseless = ((((REAL_PCRE *)re)->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)"; if (PRINTOK(need_char)) fprintf(outfile, "Need char = \'%c\'%s\n", need_char, caseless); else { fprintf(outfile, "Need char = "); pchar(need_char, outfile); fprintf(outfile, "%s\n", caseless); } } if (maxlookbehind > 0) fprintf(outfile, "Max lookbehind = %d\n", maxlookbehind); /* Don't output study size; at present it is in any case a fixed value, but it varies, depending on the computer architecture, and so messes up the test suite. (And with the /F option, it might be flipped.) If study was forced by an external -s, don't show this information unless -i or -d was also present. This means that, except when auto-callouts are involved, the output from runs with and without -s should be identical. */ if (do_study || (force_study >= 0 && showinfo && !no_force_study)) { if (extra == NULL) fprintf(outfile, "Study returned NULL\n"); else { pcre_uint8 *start_bits = NULL; int minlength; if (new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength) == 0) fprintf(outfile, "Subject length lower bound = %d\n", minlength); if (new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits) == 0) { if (start_bits == NULL) fprintf(outfile, "No set of starting bytes\n"); else { int i; int c = 24; fprintf(outfile, "Starting byte set: "); for (i = 0; i < 256; i++) { if ((start_bits[i/8] & (1<<(i&7))) != 0) { if (c > 75) { fprintf(outfile, "\n "); c = 2; } if (PRINTOK(i) && i != ' ') { fprintf(outfile, "%c ", i); c += 2; } else { fprintf(outfile, "\\x%02x ", i); c += 5; } } } fprintf(outfile, "\n"); } } } /* Show this only if the JIT was set by /S, not by -s. */ if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0) { int jit; if (new_info(re, extra, PCRE_INFO_JIT, &jit) == 0) { if (jit) fprintf(outfile, "JIT study was successful\n"); else #ifdef SUPPORT_JIT fprintf(outfile, "JIT study was not successful\n"); #else fprintf(outfile, "JIT support is not available in this version of PCRE\n"); #endif } } } } /* If the '>' option was present, we write out the regex to a file, and that is all. The first 8 bytes of the file are the regex length and then the study length, in big-endian order. */ if (to_file != NULL) { FILE *f = fopen((char *)to_file, "wb"); if (f == NULL) { fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno)); } else { pcre_uint8 sbuf[8]; if (do_flip) regexflip(re, extra); sbuf[0] = (pcre_uint8)((true_size >> 24) & 255); sbuf[1] = (pcre_uint8)((true_size >> 16) & 255); sbuf[2] = (pcre_uint8)((true_size >> 8) & 255); sbuf[3] = (pcre_uint8)((true_size) & 255); sbuf[4] = (pcre_uint8)((true_study_size >> 24) & 255); sbuf[5] = (pcre_uint8)((true_study_size >> 16) & 255); sbuf[6] = (pcre_uint8)((true_study_size >> 8) & 255); sbuf[7] = (pcre_uint8)((true_study_size) & 255); if (fwrite(sbuf, 1, 8, f) < 8 || fwrite(re, 1, true_size, f) < true_size) { fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); } else { fprintf(outfile, "Compiled pattern written to %s\n", to_file); /* If there is study data, write it. */ if (extra != NULL) { if (fwrite(extra->study_data, 1, true_study_size, f) < true_study_size) { fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); } else fprintf(outfile, "Study data written to %s\n", to_file); } } fclose(f); } new_free(re); if (extra != NULL) { PCRE_FREE_STUDY(extra); } if (locale_set) { new_free((void *)tables); setlocale(LC_CTYPE, "C"); locale_set = 0; } continue; /* With next regex */ } } /* End of non-POSIX compile */ /* Read data lines and test them */ for (;;) { pcre_uint8 *q; pcre_uint8 *bptr; int *use_offsets = offsets; int use_size_offsets = size_offsets; int callout_data = 0; int callout_data_set = 0; int count, c; int copystrings = 0; int find_match_limit = default_find_match_limit; int getstrings = 0; int getlist = 0; int gmatched = 0; int start_offset = 0; int start_offset_sign = 1; int g_notempty = 0; int use_dfa = 0; *copynames = 0; *getnames = 0; #ifdef SUPPORT_PCRE16 cn16ptr = copynames; gn16ptr = getnames; #endif #ifdef SUPPORT_PCRE8 cn8ptr = copynames8; gn8ptr = getnames8; #endif SET_PCRE_CALLOUT(callout); first_callout = 1; last_callout_mark = NULL; callout_extra = 0; callout_count = 0; callout_fail_count = 999999; callout_fail_id = -1; show_malloc = 0; options = 0; if (extra != NULL) extra->flags &= ~(PCRE_EXTRA_MATCH_LIMIT|PCRE_EXTRA_MATCH_LIMIT_RECURSION); len = 0; for (;;) { if (extend_inputline(infile, buffer + len, "data> ") == NULL) { if (len > 0) /* Reached EOF without hitting a newline */ { fprintf(outfile, "\n"); break; } done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); len = (int)strlen((char *)buffer); if (buffer[len-1] == '\n') break; } while (len > 0 && isspace(buffer[len-1])) len--; buffer[len] = 0; if (len == 0) break; p = buffer; while (isspace(*p)) p++; bptr = q = dbuffer; while ((c = *p++) != 0) { int i = 0; int n = 0; /* In UTF mode, input can be UTF-8, so just copy all non-backslash bytes. In non-UTF mode, allow the value of the byte to fall through to later, where values greater than 127 are turned into UTF-8 when running in 16-bit mode. */ if (c != '\\') { if (use_utf) { *q++ = c; continue; } } /* Handle backslash escapes */ else switch ((c = *p++)) { case 'a': c = 7; break; case 'b': c = '\b'; break; case 'e': c = 27; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') c = c * 8 + *p++ - '0'; break; case 'x': if (*p == '{') { pcre_uint8 *pt = p; c = 0; /* We used to have "while (isxdigit(*(++pt)))" here, but it fails when isxdigit() is a macro that refers to its argument more than once. This is banned by the C Standard, but apparently happens in at least one MacOS environment. */ for (pt++; isxdigit(*pt); pt++) { if (++i == 9) fprintf(outfile, "** Too many hex digits in \\x{...} item; " "using only the first eight.\n"); else c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10); } if (*pt == '}') { p = pt + 1; break; } /* Not correct form for \x{...}; fall through */ } /* \x without {} always defines just one byte in 8-bit mode. This allows UTF-8 characters to be constructed byte by byte, and also allows invalid UTF-8 sequences to be made. Just copy the byte in UTF mode. Otherwise, pass it down to later code so that it can be turned into UTF-8 when running in 16-bit mode. */ c = 0; while (i++ < 2 && isxdigit(*p)) { c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10); p++; } if (use_utf) { *q++ = c; continue; } break; case 0: /* \ followed by EOF allows for an empty line */ p--; continue; case '>': if (*p == '-') { start_offset_sign = -1; p++; } while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0'; start_offset *= start_offset_sign; continue; case 'A': /* Option setting */ options |= PCRE_ANCHORED; continue; case 'B': options |= PCRE_NOTBOL; continue; case 'C': if (isdigit(*p)) /* Set copy string */ { while(isdigit(*p)) n = n * 10 + *p++ - '0'; copystrings |= 1 << n; } else if (isalnum(*p)) { READ_CAPTURE_NAME(p, &cn8ptr, &cn16ptr, re); } else if (*p == '+') { callout_extra = 1; p++; } else if (*p == '-') { SET_PCRE_CALLOUT(NULL); p++; } else if (*p == '!') { callout_fail_id = 0; p++; while(isdigit(*p)) callout_fail_id = callout_fail_id * 10 + *p++ - '0'; callout_fail_count = 0; if (*p == '!') { p++; while(isdigit(*p)) callout_fail_count = callout_fail_count * 10 + *p++ - '0'; } } else if (*p == '*') { int sign = 1; callout_data = 0; if (*(++p) == '-') { sign = -1; p++; } while(isdigit(*p)) callout_data = callout_data * 10 + *p++ - '0'; callout_data *= sign; callout_data_set = 1; } continue; #if !defined NODFA case 'D': #if !defined NOPOSIX if (posix || do_posix) printf("** Can't use dfa matching in POSIX mode: \\D ignored\n"); else #endif use_dfa = 1; continue; #endif #if !defined NODFA case 'F': options |= PCRE_DFA_SHORTEST; continue; #endif case 'G': if (isdigit(*p)) { while(isdigit(*p)) n = n * 10 + *p++ - '0'; getstrings |= 1 << n; } else if (isalnum(*p)) { READ_CAPTURE_NAME(p, &gn8ptr, &gn16ptr, re); } continue; case 'J': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (extra != NULL && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) { if (jit_stack != NULL) { PCRE_JIT_STACK_FREE(jit_stack); } jit_stack = PCRE_JIT_STACK_ALLOC(1, n * 1024); PCRE_ASSIGN_JIT_STACK(extra, jit_callback, jit_stack); } continue; case 'L': getlist = 1; continue; case 'M': find_match_limit = 1; continue; case 'N': if ((options & PCRE_NOTEMPTY) != 0) options = (options & ~PCRE_NOTEMPTY) | PCRE_NOTEMPTY_ATSTART; else options |= PCRE_NOTEMPTY; continue; case 'O': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (n > size_offsets_max) { size_offsets_max = n; free(offsets); use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", (int)(size_offsets_max * sizeof(int))); yield = 1; goto EXIT; } } use_size_offsets = n; if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ else use_offsets = offsets + size_offsets_max - n; /* To catch overruns */ continue; case 'P': options |= ((options & PCRE_PARTIAL_SOFT) == 0)? PCRE_PARTIAL_SOFT : PCRE_PARTIAL_HARD; 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; continue; #endif case 'S': show_malloc = 1; continue; case 'Y': options |= PCRE_NO_START_OPTIMIZE; continue; case 'Z': options |= PCRE_NOTEOL; continue; 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; } /* We now have a character value in c that may be greater than 255. In 16-bit mode, we always convert characters to UTF-8 so that values greater than 255 can be passed to non-UTF 16-bit strings. In 8-bit mode we convert to UTF-8 if we are in UTF mode. Values greater than 127 in UTF mode must have come from \x{...} or octal constructs because values from \x.. get this far only in non-UTF mode. */ #if !defined NOUTF || defined SUPPORT_PCRE16 if (use_pcre16 || use_utf) { pcre_uint8 buff8[8]; int ii, utn; utn = ord2utf8(c, buff8); for (ii = 0; ii < utn; ii++) *q++ = buff8[ii]; } else #endif { if (c > 255) { fprintf(outfile, "** Character \\x{%x} is greater than 255 " "and UTF-8 mode is not enabled.\n", c); fprintf(outfile, "** Truncation will probably give the wrong " "result.\n"); } *q++ = c; } } /* Reached end of subject string */ *q = 0; len = (int)(q - dbuffer); /* Move the data to the end of the buffer so that a read over the end of the buffer will be seen by valgrind, even if it doesn't cause a crash. If we are using the POSIX interface, we must include the terminating zero. */ #if !defined NOPOSIX if (posix || do_posix) { memmove(bptr + buffer_size - len - 1, bptr, len + 1); bptr += buffer_size - len - 1; } else #endif { memmove(bptr + buffer_size - len, bptr, len); bptr += buffer_size - len; } if ((all_use_dfa || use_dfa) && find_match_limit) { printf("**Match limit not relevant for DFA matching: ignored\n"); find_match_limit = 0; } /* Handle matching via the POSIX interface, which does not support timing or playing with the match limit or callout data. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int eflags = 0; regmatch_t *pmatch = NULL; if (use_size_offsets > 0) pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; if ((options & PCRE_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY; rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); if (rc != 0) { (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) != 0) { fprintf(outfile, "Matched with REG_NOSUB\n"); } else { size_t i; for (i = 0; i < (size_t)use_size_offsets; i++) { if (pmatch[i].rm_so >= 0) { fprintf(outfile, "%2d: ", (int)i); PCHARSV(dbuffer, pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so, outfile); fprintf(outfile, "\n"); if (do_showcaprest || (i == 0 && do_showrest)) { fprintf(outfile, "%2d+ ", (int)i); PCHARSV(dbuffer, pmatch[i].rm_eo, len - pmatch[i].rm_eo, outfile); fprintf(outfile, "\n"); } } } } free(pmatch); goto NEXT_DATA; } #endif /* !defined NOPOSIX */ /* Handle matching via the native interface - repeats for /g and /G */ #ifdef SUPPORT_PCRE16 if (use_pcre16) { len = to16(TRUE, bptr, (((REAL_PCRE *)re)->options) & PCRE_UTF8, len); switch(len) { case -1: fprintf(outfile, "**Failed: invalid UTF-8 string cannot be " "converted to UTF-16\n"); goto NEXT_DATA; case -2: fprintf(outfile, "**Failed: character value greater than 0x10ffff " "cannot be converted to UTF-16\n"); goto NEXT_DATA; case -3: fprintf(outfile, "**Failed: character value greater than 0xffff " "cannot be converted to 16-bit in non-UTF mode\n"); goto NEXT_DATA; default: break; } bptr = (pcre_uint8 *)buffer16; } #endif /* Ensure that there is a JIT callback if we want to verify that JIT was actually used. If jit_stack == NULL, no stack has yet been assigned. */ if (verify_jit && jit_stack == NULL && extra != NULL) { PCRE_ASSIGN_JIT_STACK(extra, jit_callback, jit_stack); } for (;; gmatched++) /* Loop for /g or /G */ { markptr = NULL; jit_was_used = FALSE; if (timeitm > 0) { register int i; clock_t time_taken; clock_t start_time = clock(); #if !defined NODFA if (all_use_dfa || use_dfa) { if ((options & PCRE_DFA_RESTART) != 0) { fprintf(outfile, "Timing DFA restarts is not supported\n"); break; } if (dfa_workspace == NULL) dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); for (i = 0; i < timeitm; i++) { PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, (options | g_notempty), use_offsets, use_size_offsets, dfa_workspace, DFA_WS_DIMENSION); } } else #endif for (i = 0; i < timeitm; i++) { PCRE_EXEC(count, re, extra, bptr, len, start_offset, (options | g_notempty), use_offsets, use_size_offsets); } time_taken = clock() - start_time; fprintf(outfile, "Execute time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeitm) / (double)CLOCKS_PER_SEC); } /* If find_match_limit is set, we want to do repeated matches with varying limits in order to find the minimum value for the match limit and for the recursion limit. The match limits are relevant only to the normal running of pcre_exec(), so disable the JIT optimization. This makes it possible to run the same set of tests with and without JIT externally requested. */ if (find_match_limit) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } else extra->flags &= ~PCRE_EXTRA_EXECUTABLE_JIT; (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()"); count = check_match_limit(re, extra, bptr, len, start_offset, options|g_notempty, use_offsets, use_size_offsets, PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion), PCRE_ERROR_RECURSIONLIMIT, "match() recursion"); } /* If callout_data is set, use the interface with additional data */ else if (callout_data_set) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_CALLOUT_DATA; extra->callout_data = &callout_data; PCRE_EXEC(count, re, extra, bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; } /* The normal case is just to do the match once, with the default value of match_limit. */ #if !defined NODFA else if (all_use_dfa || use_dfa) { if (dfa_workspace == NULL) dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); if (dfa_matched++ == 0) dfa_workspace[0] = -1; /* To catch bad restart */ PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, (options | g_notempty), use_offsets, use_size_offsets, dfa_workspace, DFA_WS_DIMENSION); if (count == 0) { fprintf(outfile, "Matched, but too many subsidiary matches\n"); count = use_size_offsets/2; } } #endif else { PCRE_EXEC(count, re, extra, bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); count = use_size_offsets/3; } } /* Matched */ if (count >= 0) { int i, maxcount; void *cnptr, *gnptr; #if !defined NODFA if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else #endif maxcount = use_size_offsets/3; /* This is a check against a lunatic return value. */ if (count > maxcount) { fprintf(outfile, "** PCRE error: returned count %d is too big for offset size %d\n", count, use_size_offsets); count = use_size_offsets/3; if (do_g || do_G) { fprintf(outfile, "** /%c loop abandoned\n", do_g? 'g' : 'G'); do_g = do_G = FALSE; /* Break g/G loop */ } } /* do_allcaps requests showing of all captures in the pattern, to check unset ones at the end. */ if (do_allcaps) { if (new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count) < 0) goto SKIP_DATA; count++; /* Allow for full match */ if (count * 2 > use_size_offsets) count = use_size_offsets/2; } /* Output the captured substrings */ for (i = 0; i < count * 2; i += 2) { if (use_offsets[i] < 0) { if (use_offsets[i] != -1) fprintf(outfile, "ERROR: bad negative value %d for offset %d\n", use_offsets[i], i); if (use_offsets[i+1] != -1) fprintf(outfile, "ERROR: bad negative value %d for offset %d\n", use_offsets[i+1], i+1); fprintf(outfile, "%2d: \n", i/2); } else { fprintf(outfile, "%2d: ", i/2); PCHARSV(bptr, use_offsets[i], use_offsets[i+1] - use_offsets[i], outfile); if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)"); fprintf(outfile, "\n"); if (do_showcaprest || (i == 0 && do_showrest)) { fprintf(outfile, "%2d+ ", i/2); PCHARSV(bptr, use_offsets[i+1], len - use_offsets[i+1], outfile); fprintf(outfile, "\n"); } } } if (markptr != NULL) { fprintf(outfile, "MK: "); PCHARSV(markptr, 0, -1, outfile); fprintf(outfile, "\n"); } for (i = 0; i < 32; i++) { if ((copystrings & (1 << i)) != 0) { int rc; char copybuffer[256]; PCRE_COPY_SUBSTRING(rc, bptr, use_offsets, count, i, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %d failed %d\n", i, rc); else { fprintf(outfile, "%2dC ", i); PCHARSV(copybuffer, 0, rc, outfile); fprintf(outfile, " (%d)\n", rc); } } } cnptr = copynames; for (;;) { int rc; char copybuffer[256]; if (use_pcre16) { if (*(pcre_uint16 *)cnptr == 0) break; } else { if (*(pcre_uint8 *)cnptr == 0) break; } PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, use_offsets, count, cnptr, copybuffer, sizeof(copybuffer)); if (rc < 0) { fprintf(outfile, "copy substring "); PCHARSV(cnptr, 0, -1, outfile); fprintf(outfile, " failed %d\n", rc); } else { fprintf(outfile, " C "); PCHARSV(copybuffer, 0, rc, outfile); fprintf(outfile, " (%d) ", rc); PCHARSV(cnptr, 0, -1, outfile); putc('\n', outfile); } cnptr = (char *)cnptr + (STRLEN(cnptr) + 1) * CHAR_SIZE; } for (i = 0; i < 32; i++) { if ((getstrings & (1 << i)) != 0) { int rc; const char *substring; PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, &substring); if (rc < 0) fprintf(outfile, "get substring %d failed %d\n", i, rc); else { fprintf(outfile, "%2dG ", i); PCHARSV(substring, 0, rc, outfile); fprintf(outfile, " (%d)\n", rc); PCRE_FREE_SUBSTRING(substring); } } } gnptr = getnames; for (;;) { int rc; const char *substring; if (use_pcre16) { if (*(pcre_uint16 *)gnptr == 0) break; } else { if (*(pcre_uint8 *)gnptr == 0) break; } PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, use_offsets, count, gnptr, &substring); if (rc < 0) { fprintf(outfile, "get substring "); PCHARSV(gnptr, 0, -1, outfile); fprintf(outfile, " failed %d\n", rc); } else { fprintf(outfile, " G "); PCHARSV(substring, 0, rc, outfile); fprintf(outfile, " (%d) ", rc); PCHARSV(gnptr, 0, -1, outfile); PCRE_FREE_SUBSTRING(substring); putc('\n', outfile); } gnptr = (char *)gnptr + (STRLEN(gnptr) + 1) * CHAR_SIZE; } if (getlist) { int rc; const char **stringlist; PCRE_GET_SUBSTRING_LIST(rc, bptr, use_offsets, count, &stringlist); if (rc < 0) fprintf(outfile, "get substring list failed %d\n", rc); else { for (i = 0; i < count; i++) { fprintf(outfile, "%2dL ", i); PCHARSV(stringlist[i], 0, -1, outfile); putc('\n', outfile); } if (stringlist[i] != NULL) fprintf(outfile, "string list not terminated by NULL\n"); PCRE_FREE_SUBSTRING_LIST(stringlist); } } } /* There was a partial match */ else if (count == PCRE_ERROR_PARTIAL) { if (markptr == NULL) fprintf(outfile, "Partial match"); else { fprintf(outfile, "Partial match, mark="); PCHARSV(markptr, 0, -1, outfile); } if (use_size_offsets > 1) { fprintf(outfile, ": "); PCHARSV(bptr, use_offsets[0], use_offsets[1] - use_offsets[0], outfile); } if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)"); fprintf(outfile, "\n"); break; /* Out of the /g loop */ } /* Failed to match. If this is a /g or /G loop and we previously set g_notempty after a null match, this is not necessarily the end. We want to advance the start offset, and continue. We won't be at the end of the string - that was checked before setting g_notempty. Complication arises in the case when the newline convention is "any", "crlf", or "anycrlf". If the previous match was at the end of a line terminated by CRLF, an advance of one character just passes the \r, whereas we should prefer the longer newline sequence, as does the code in pcre_exec(). Fudge the offset value to achieve this. We check for a newline setting in the pattern; if none was set, use PCRE_CONFIG() to find the default. Otherwise, in the case of UTF-8 matching, the advance must be one character, not one byte. */ else { if (g_notempty != 0) { int onechar = 1; unsigned int obits = ((REAL_PCRE *)re)->options; use_offsets[0] = start_offset; if ((obits & PCRE_NEWLINE_BITS) == 0) { int d; (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &d); /* Note that these values are always the ASCII ones, even in EBCDIC environments. CR = 13, NL = 10. */ obits = (d == 13)? PCRE_NEWLINE_CR : (d == 10)? PCRE_NEWLINE_LF : (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF : (d == -2)? PCRE_NEWLINE_ANYCRLF : (d == -1)? PCRE_NEWLINE_ANY : 0; } if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY || (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_CRLF || (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF) && start_offset < len - 1 && #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 (use_pcre16? ((PCRE_SPTR16)bptr)[start_offset] == '\r' && ((PCRE_SPTR16)bptr)[start_offset + 1] == '\n' : bptr[start_offset] == '\r' && bptr[start_offset + 1] == '\n') #elif defined SUPPORT_PCRE16 ((PCRE_SPTR16)bptr)[start_offset] == '\r' && ((PCRE_SPTR16)bptr)[start_offset + 1] == '\n' #else bptr[start_offset] == '\r' && bptr[start_offset + 1] == '\n' #endif ) onechar++; else if (use_utf) { while (start_offset + onechar < len) { if ((bptr[start_offset+onechar] & 0xc0) != 0x80) break; onechar++; } } use_offsets[1] = start_offset + onechar; } else { switch(count) { case PCRE_ERROR_NOMATCH: if (gmatched == 0) { if (markptr == NULL) { fprintf(outfile, "No match"); } else { fprintf(outfile, "No match, mark = "); PCHARSV(markptr, 0, -1, outfile); } if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)"); putc('\n', outfile); } break; case PCRE_ERROR_BADUTF8: case PCRE_ERROR_SHORTUTF8: fprintf(outfile, "Error %d (%s UTF-%s string)", count, (count == PCRE_ERROR_BADUTF8)? "bad" : "short", use_pcre16? "16" : "8"); if (use_size_offsets >= 2) fprintf(outfile, " offset=%d reason=%d", use_offsets[0], use_offsets[1]); fprintf(outfile, "\n"); break; case PCRE_ERROR_BADUTF8_OFFSET: fprintf(outfile, "Error %d (bad UTF-%s offset)\n", count, use_pcre16? "16" : "8"); break; default: if (count < 0 && (-count) < (int)(sizeof(errtexts)/sizeof(const char *))) fprintf(outfile, "Error %d (%s)\n", count, errtexts[-count]); else fprintf(outfile, "Error %d (Unexpected value)\n", count); break; } break; /* Out of the /g loop */ } } /* If not /g or /G we are done */ if (!do_g && !do_G) break; /* 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_ATSTART 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 (use_offsets[0] == use_offsets[1]) { if (use_offsets[0] == len) break; g_notempty = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED; } /* For /g, update the start offset, leaving the rest alone */ if (do_g) start_offset = use_offsets[1]; /* For /G, update the pointer and length */ else { bptr += use_offsets[1] * CHAR_SIZE; len -= use_offsets[1]; } } /* End of loop for /g and /G */ NEXT_DATA: continue; } /* End of loop for data lines */ CONTINUE: #if !defined NOPOSIX if (posix || do_posix) regfree(&preg); #endif if (re != NULL) new_free(re); if (extra != NULL) { PCRE_FREE_STUDY(extra); } if (locale_set) { new_free((void *)tables); setlocale(LC_CTYPE, "C"); locale_set = 0; } if (jit_stack != NULL) { PCRE_JIT_STACK_FREE(jit_stack); jit_stack = NULL; } } if (infile == stdin) fprintf(outfile, "\n"); EXIT: if (infile != NULL && infile != stdin) fclose(infile); if (outfile != NULL && outfile != stdout) fclose(outfile); free(buffer); free(dbuffer); free(pbuffer); free(offsets); #ifdef SUPPORT_PCRE16 if (buffer16 != NULL) free(buffer16); #endif return yield; } /* End of pcretest.c */ pcre-8.31/RunGrepTest0000755000222100022210000005464711724716330011477 00000000000000#! /bin/sh # Run pcregrep tests. The assumption is that the PCRE tests check the library # itself. What we are checking here is the file handling and options that are # supported by pcregrep. # Set the C locale, so that sort(1) behaves predictably. LC_ALL=C export LC_ALL # Remove any non-default colouring and aliases that the caller may have set. unset PCREGREP_COLOUR PCREGREP_COLOR unset cp ls mv rm # Set the program to be tested, and valgrind settings when requested. pcregrep=`pwd`/pcregrep valgrind= while [ $# -gt 0 ] ; do case $1 in valgrind) valgrind="valgrind -q --leak-check=no --smc-check=all";; *) echo "RunGrepTest: Unknown argument $1"; exit 1;; esac shift done echo " " if [ "$valgrind" = "" ] ; then echo "Testing pcregrep" else echo "Testing pcregrep using valgrind" fi $pcregrep -V # Set up a suitable "diff" command for comparison. Some systems have a diff # that lacks a -u option. Try to deal with this; better do the test for the -b # option as well. cf="diff -ub" if diff -u /dev/null /dev/null; then if diff -ub /dev/null /dev/null; then cf="diff -ub"; else cf="diff -u"; fi else if diff -b /dev/null /dev/null; then cf="diff -b"; else cf="diff"; fi fi # If PCRE has been built in a directory other than the source directory, and # this test is being run from "make check" as usual, then $srcdir will be # set. If not, set it to the current or parent directory, whichever one # contains the test data. We then arrange to run the pcregrep command in the # source directory so that the file names that appear in the output are always # the same. if [ -z "$srcdir" -o ! -d "$srcdir/testdata" ] ; then if [ -d "./testdata" ] ; then srcdir=. elif [ -d "../testdata" ] ; then srcdir=.. else echo "Cannot find the testdata directory" exit 1 fi fi # Check for the availability of UTF-8 support ./pcretest -C utf >/dev/null utf8=$? echo "---------------------------- Test 1 ------------------------------" >testtry (cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 2 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 3 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 4 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 5 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 6 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 7 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 8 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 9 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 10 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 11 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 12 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 13 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -f./testdata/greplist ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 14 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 15 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtry >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 16 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtry >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 17 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 18 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 19 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 20 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 21 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 22 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 23 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 24 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 25 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 26 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 27 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 28 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 29 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 30 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 31 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 32 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 33 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 34 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 35 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --exclude-dir='^\.' 'fox' ./testdata) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 36 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' --exclude_dir='^\.' 'fox' ./testdata | sort) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 37 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtry 2>teststderr echo "RC=$?" >>testtry echo "======== STDERR ========" >>testtry cat teststderr >>testtry echo "---------------------------- Test 38 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 39 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 40 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 41 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 42 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 43 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 44 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -on -e before -ezero -e after ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 45 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 46 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtry >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 47 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Fx "AB.VE elephant" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 48 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -F "AB.VE elephant" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 49 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -F -e DATA -e "AB.VE elephant" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 50 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 51 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 52 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --colour=always jumps ./testdata/grepinputv) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 53 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 54 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 55 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 56 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -c lazy ./testdata/grepinput*) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 57 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -c -l lazy ./testdata/grepinput*) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 58 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --regex=PATTERN ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 59 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --regexp=PATTERN ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 60 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --regex PATTERN ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 61 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --regexp PATTERN ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 62 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --match-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 63 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --recursion-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 64 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 65 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 66 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 67 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 68 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 69 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -vn --colour=always pattern ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 70 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 71 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o "^01|^02|^03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 72 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 73 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 74 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o "^01|02|^03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 75 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --color=always "^01|02|^03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 76 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 77 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o "^01|^02|03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 78 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 79 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 80 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o "\b01|\b02" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 81 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 82 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 83 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 84 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist "fox|complete") >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 85 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 86 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep "dog" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 87 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep "cat" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 88 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -v "cat" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 89 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -I "dog" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 90 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 91 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -a "dog" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 92 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --binary-files=text "dog" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 93 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep --text "dog" ./testdata/grepbinary) >>testtry 2>&1 echo "RC=$?" >>testtry # Now compare the results. $cf $srcdir/testdata/grepoutput testtry if [ $? != 0 ] ; then exit 1; fi # These tests require UTF-8 support if [ $utf8 -ne 0 ] ; then echo "Testing pcregrep UTF-8 features" echo "---------------------------- Test U1 ------------------------------" >testtry (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test U2 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtry echo "RC=$?" >>testtry $cf $srcdir/testdata/grepoutput8 testtry if [ $? != 0 ] ; then exit 1; fi else echo "Skipping pcregrep UTF-8 tests: no UTF-8 support in PCRE library" fi # We go to some contortions to try to ensure that the tests for the various # newline settings will work in environments where the normal newline sequence # is not \n. Do not use exported files, whose line endings might be changed. # Instead, create an input file using printf so that its contents are exactly # what we want. Note the messy fudge to get printf to write a string that # starts with a hyphen. echo "Testing pcregrep newline settings" printf "abc\rdef\r\nghi\njkl" >testNinput printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtry $valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinput >>testtry printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinput >>testtry printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtry pattern=`printf 'def\rjkl'` $valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinput >>testtry printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinput >>testtry printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinput >>testtry $cf $srcdir/testdata/grepoutputN testtry if [ $? != 0 ] ; then exit 1; fi exit 0 # End pcre-8.31/pcre_exec.c0000644000222100022210000065320511770142643011424 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains pcre_exec(), the externally visible function that does pattern matching using an NFA algorithm, trying to mimic Perl as closely as possible. There are also some static supporting functions. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define NLBLOCK md /* Block containing newline information */ #define PSSTART start_subject /* Field containing processed string start */ #define PSEND end_subject /* Field containing processed string end */ #include "pcre_internal.h" /* Undefine some potentially clashing cpp symbols */ #undef min #undef max /* Values for setting in md->match_function_type to indicate two special types of call to match(). We do it this way to save on using another stack variable, as stack usage is to be discouraged. */ #define MATCH_CONDASSERT 1 /* Called to check a condition assertion */ #define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */ /* Non-error returns from the match() function. Error returns are externally defined PCRE_ERROR_xxx codes, which are all negative. */ #define MATCH_MATCH 1 #define MATCH_NOMATCH 0 /* Special internal returns from the match() function. Make them sufficiently negative to avoid the external error codes. */ #define MATCH_ACCEPT (-999) #define MATCH_COMMIT (-998) #define MATCH_KETRPOS (-997) #define MATCH_ONCE (-996) #define MATCH_PRUNE (-995) #define MATCH_SKIP (-994) #define MATCH_SKIP_ARG (-993) #define MATCH_THEN (-992) /* Maximum number of ints of offset to save on the stack for recursive calls. If the offset vector is bigger, malloc is used. This should be a multiple of 3, because the offset vector is always a multiple of 3 long. */ #define REC_STACK_SAVE_MAX 30 /* Min and max values for the common repeats; for the maxima, 0 => infinity */ static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; #ifdef PCRE_DEBUG /************************************************* * Debugging function to print chars * *************************************************/ /* Print a sequence of chars in printable format, stopping at the end of the subject if the requested. Arguments: p points to characters length number to print is_subject TRUE if printing from within md->start_subject md pointer to matching data block, if is_subject is TRUE Returns: nothing */ static void pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md) { unsigned int c; if (is_subject && length > md->end_subject - p) length = md->end_subject - p; while (length-- > 0) if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c); } #endif /************************************************* * Match a back-reference * *************************************************/ /* Normally, if a back reference hasn't been set, the length that is passed is negative, so the match always fails. However, in JavaScript compatibility mode, the length passed is zero. Note that in caseless UTF-8 mode, the number of subject bytes matched may be different to the number of reference bytes. Arguments: offset index into the offset vector eptr pointer into the subject length length of reference to be matched (number of bytes) md points to match data block caseless TRUE if caseless Returns: >= 0 the number of subject bytes matched -1 no match -2 partial match; always given if at end subject */ static int match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md, BOOL caseless) { PCRE_PUCHAR eptr_start = eptr; register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset]; #ifdef PCRE_DEBUG if (eptr >= md->end_subject) printf("matching subject "); else { printf("matching subject "); pchars(eptr, length, TRUE, md); } printf(" against backref "); pchars(p, length, FALSE, md); printf("\n"); #endif /* Always fail if reference not set (and not JavaScript compatible - in that case the length is passed as zero). */ if (length < 0) return -1; /* Separate the caseless case for speed. In UTF-8 mode we can only do this properly if Unicode properties are supported. Otherwise, we can check only ASCII characters. */ if (caseless) { #ifdef SUPPORT_UTF #ifdef SUPPORT_UCP if (md->utf) { /* Match characters up to the end of the reference. NOTE: the number of bytes matched may differ, because there are some characters whose upper and lower case versions code as different numbers of bytes. For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a sequence of two of the latter. It is important, therefore, to check the length along the reference, not along the subject (earlier code did this wrong). */ PCRE_PUCHAR endptr = p + length; while (p < endptr) { int c, d; if (eptr >= md->end_subject) return -2; /* Partial match */ GETCHARINC(c, eptr); GETCHARINC(d, p); if (c != d && c != UCD_OTHERCASE(d)) return -1; } } else #endif #endif /* The same code works when not in UTF-8 mode and in UTF-8 mode when there is no UCP support. */ { while (length-- > 0) { if (eptr >= md->end_subject) return -2; /* Partial match */ if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; p++; eptr++; } } } /* In the caseful case, we can just compare the bytes, whether or not we are in UTF-8 mode. */ else { while (length-- > 0) { if (eptr >= md->end_subject) return -2; /* Partial match */ if (*p++ != *eptr++) return -1; } } return (int)(eptr - eptr_start); } /*************************************************************************** **************************************************************************** RECURSION IN THE match() FUNCTION The match() function is highly recursive, though not every recursive call increases the recursive depth. Nevertheless, some regular expressions can cause it to recurse to a great depth. I was writing for Unix, so I just let it call itself recursively. This uses the stack for saving everything that has to be saved for a recursive call. On Unix, the stack can be large, and this works fine. It turns out that on some non-Unix-like systems there are problems with programs that use a lot of stack. (This despite the fact that every last chip has oodles of memory these days, and techniques for extending the stack have been known for decades.) So.... There is a fudge, triggered by defining NO_RECURSE, which avoids recursive calls by keeping local variables that need to be preserved in blocks of memory obtained from malloc() instead instead of on the stack. Macros are used to achieve this so that the actual code doesn't look very different to what it always used to. The original heap-recursive code used longjmp(). However, it seems that this can be very slow on some operating systems. Following a suggestion from Stan Switzer, the use of longjmp() has been abolished, at the cost of having to provide a unique number for each call to RMATCH. There is no way of generating a sequence of numbers at compile time in C. I have given them names, to make them stand out more clearly. Crude tests on x86 Linux show a small speedup of around 5-8%. However, on FreeBSD, avoiding longjmp() more than halves the time taken to run the standard tests. Furthermore, not using longjmp() means that local dynamic variables don't have indeterminate values; this has meant that the frame size can be reduced because the result can be "passed back" by straight setting of the variable instead of being passed in the frame. **************************************************************************** ***************************************************************************/ /* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN below must be updated in sync. */ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50, RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60, RM61, RM62, RM63, RM64, RM65, RM66 }; /* These versions of the macros use the stack, as normal. There are debugging versions and production versions. Note that the "rw" argument of RMATCH isn't actually used in this definition. */ #ifndef NO_RECURSE #define REGISTER register #ifdef PCRE_DEBUG #define RMATCH(ra,rb,rc,rd,re,rw) \ { \ printf("match() called in line %d\n", __LINE__); \ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \ printf("to line %d\n", __LINE__); \ } #define RRETURN(ra) \ { \ printf("match() returned %d from line %d ", ra, __LINE__); \ return ra; \ } #else #define RMATCH(ra,rb,rc,rd,re,rw) \ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1) #define RRETURN(ra) return ra #endif #else /* These versions of the macros manage a private stack on the heap. Note that the "rd" argument of RMATCH isn't actually used in this definition. It's the md argument of match(), which never changes. */ #define REGISTER #define RMATCH(ra,rb,rc,rd,re,rw)\ {\ heapframe *newframe = frame->Xnextframe;\ if (newframe == NULL)\ {\ newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\ if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ newframe->Xnextframe = NULL;\ frame->Xnextframe = newframe;\ }\ frame->Xwhere = rw;\ newframe->Xeptr = ra;\ newframe->Xecode = rb;\ newframe->Xmstart = mstart;\ newframe->Xoffset_top = rc;\ newframe->Xeptrb = re;\ newframe->Xrdepth = frame->Xrdepth + 1;\ newframe->Xprevframe = frame;\ frame = newframe;\ DPRINTF(("restarting from line %d\n", __LINE__));\ goto HEAP_RECURSE;\ L_##rw:\ DPRINTF(("jumped back to line %d\n", __LINE__));\ } #define RRETURN(ra)\ {\ heapframe *oldframe = frame;\ frame = oldframe->Xprevframe;\ if (frame != NULL)\ {\ rrc = ra;\ goto HEAP_RETURN;\ }\ return ra;\ } /* Structure for remembering the local variables in a private frame */ typedef struct heapframe { struct heapframe *Xprevframe; struct heapframe *Xnextframe; /* Function arguments that may change */ PCRE_PUCHAR Xeptr; const pcre_uchar *Xecode; PCRE_PUCHAR Xmstart; int Xoffset_top; eptrblock *Xeptrb; unsigned int Xrdepth; /* Function local variables */ PCRE_PUCHAR Xcallpat; #ifdef SUPPORT_UTF PCRE_PUCHAR Xcharptr; #endif PCRE_PUCHAR Xdata; PCRE_PUCHAR Xnext; PCRE_PUCHAR Xpp; PCRE_PUCHAR Xprev; PCRE_PUCHAR Xsaved_eptr; recursion_info Xnew_recursive; BOOL Xcur_is_word; BOOL Xcondition; BOOL Xprev_is_word; #ifdef SUPPORT_UCP int Xprop_type; int Xprop_value; int Xprop_fail_result; int Xoclength; pcre_uchar Xocchars[6]; #endif int Xcodelink; int Xctype; unsigned int Xfc; int Xfi; int Xlength; int Xmax; int Xmin; int Xnumber; int Xoffset; int Xop; int Xsave_capture_last; int Xsave_offset1, Xsave_offset2, Xsave_offset3; int Xstacksave[REC_STACK_SAVE_MAX]; eptrblock Xnewptrb; /* Where to jump back to */ int Xwhere; } heapframe; #endif /*************************************************************************** ***************************************************************************/ /************************************************* * Match from current position * *************************************************/ /* This function is called recursively in many circumstances. Whenever it returns a negative (error) response, the outer incarnation must also return the same response. */ /* These macros pack up tests that are used for partial matching, and which appear several times in the code. We set the "hit end" flag if the pointer is at the end of the subject and also past the start of the subject (i.e. something has been matched). For hard partial matching, we then return immediately. The second one is used when we already know we are past the end of the subject. */ #define CHECK_PARTIAL()\ if (md->partial != 0 && eptr >= md->end_subject && \ eptr > md->start_used_ptr) \ { \ md->hitend = TRUE; \ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \ } #define SCHECK_PARTIAL()\ if (md->partial != 0 && eptr > md->start_used_ptr) \ { \ md->hitend = TRUE; \ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \ } /* Performance note: It might be tempting to extract commonly used fields from the md structure (e.g. utf, end_subject) into individual variables to improve performance. Tests using gcc on a SPARC disproved this; in the first case, it made performance worse. Arguments: eptr pointer to current character in subject ecode pointer to current position in compiled code mstart pointer to the current match start position (can be modified by encountering \K) offset_top current top pointer md pointer to "static" info for the match eptrb pointer to chain of blocks containing eptr at start of brackets - for testing for empty matches rdepth the recursion depth Returns: MATCH_MATCH if matched ) these values are >= 0 MATCH_NOMATCH if failed to match ) a negative MATCH_xxx value for PRUNE, SKIP, etc a negative PCRE_ERROR_xxx value if aborted by an error condition (e.g. stopped by repeated call or recursion limit) */ static int match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode, PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb, 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 some of 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 unsigned int c; /* Character values not kept over RMATCH() calls */ register BOOL utf; /* Local copy of UTF flag for speed */ BOOL minimize, possessive; /* Quantifier options */ BOOL caseless; int condcode; /* When recursion is not being used, all "local" variables that have to be preserved over calls to RMATCH() are part of a "frame". We set up the top-level frame on the stack here; subsequent instantiations are obtained from the heap whenever RMATCH() does a "recursion". See the macro definitions above. Putting the top-level on the stack rather than malloc-ing them all gives a performance boost in many cases where there is not much "recursion". */ #ifdef NO_RECURSE heapframe *frame = (heapframe *)md->match_frames_base; /* Copy in the original argument variables */ frame->Xeptr = eptr; frame->Xecode = ecode; frame->Xmstart = mstart; frame->Xoffset_top = offset_top; frame->Xeptrb = eptrb; frame->Xrdepth = rdepth; /* This is where control jumps back to to effect "recursion" */ HEAP_RECURSE: /* Macros make the argument variables come from the current frame */ #define eptr frame->Xeptr #define ecode frame->Xecode #define mstart frame->Xmstart #define offset_top frame->Xoffset_top #define eptrb frame->Xeptrb #define rdepth frame->Xrdepth /* Ditto for the local variables */ #ifdef SUPPORT_UTF #define charptr frame->Xcharptr #endif #define callpat frame->Xcallpat #define codelink frame->Xcodelink #define data frame->Xdata #define next frame->Xnext #define pp frame->Xpp #define prev frame->Xprev #define saved_eptr frame->Xsaved_eptr #define new_recursive frame->Xnew_recursive #define cur_is_word frame->Xcur_is_word #define condition frame->Xcondition #define prev_is_word frame->Xprev_is_word #ifdef SUPPORT_UCP #define prop_type frame->Xprop_type #define prop_value frame->Xprop_value #define prop_fail_result frame->Xprop_fail_result #define oclength frame->Xoclength #define occhars frame->Xocchars #endif #define ctype frame->Xctype #define fc frame->Xfc #define fi frame->Xfi #define length frame->Xlength #define max frame->Xmax #define min frame->Xmin #define number frame->Xnumber #define offset frame->Xoffset #define op frame->Xop #define save_capture_last frame->Xsave_capture_last #define save_offset1 frame->Xsave_offset1 #define save_offset2 frame->Xsave_offset2 #define save_offset3 frame->Xsave_offset3 #define stacksave frame->Xstacksave #define newptrb frame->Xnewptrb /* When recursion is being used, local variables are allocated on the stack and get preserved during recursion in the normal way. In this environment, fi and i, and fc and c, can be the same variables. */ #else /* NO_RECURSE not defined */ #define fi i #define fc c /* Many of the following variables are used only in small blocks of the code. My normal style of coding would have declared them within each of those blocks. However, in order to accommodate the version of this code that uses an external "stack" implemented on the heap, it is easier to declare them all here, so the declarations can be cut out in a block. The only declarations within blocks below are for variables that do not have to be preserved over a recursive call to RMATCH(). */ #ifdef SUPPORT_UTF const pcre_uchar *charptr; #endif const pcre_uchar *callpat; const pcre_uchar *data; const pcre_uchar *next; PCRE_PUCHAR pp; const pcre_uchar *prev; PCRE_PUCHAR saved_eptr; recursion_info new_recursive; BOOL cur_is_word; BOOL condition; BOOL prev_is_word; #ifdef SUPPORT_UCP int prop_type; int prop_value; int prop_fail_result; int oclength; pcre_uchar occhars[6]; #endif int codelink; int ctype; int length; int max; int min; int number; int offset; int op; int save_capture_last; int save_offset1, save_offset2, save_offset3; int stacksave[REC_STACK_SAVE_MAX]; eptrblock newptrb; /* There is a special fudge for calling match() in a way that causes it to measure the size of its basic stack frame when the stack is being used for recursion. The second argument (ecode) being NULL triggers this behaviour. It cannot normally ever be NULL. The return is the negated value of the frame size. */ if (ecode == NULL) { if (rdepth == 0) return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1); else { int len = (char *)&rdepth - (char *)eptr; return (len > 0)? -len : len; } } #endif /* NO_RECURSE */ /* To save space on the stack and in the heap frame, I have doubled up on some of the local variables that are used only in localised parts of the code, but still need to be preserved over recursive calls of match(). These macros define the alternative names that are used. */ #define allow_zero cur_is_word #define cbegroup condition #define code_offset codelink #define condassert condition #define matched_once prev_is_word #define foc number #define save_mark data /* These statements are here to stop the compiler complaining about unitialized variables. */ #ifdef SUPPORT_UCP prop_value = 0; prop_fail_result = 0; #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() and a "return", respectively (possibly with some debugging if PCRE_DEBUG is defined). However, RMATCH isn't like a function call because it's quite a complicated macro. It has to be used in one particular way. This shouldn't, however, impact performance when true recursion is being used. */ #ifdef SUPPORT_UTF utf = md->utf; /* Local copy of the flag */ #else utf = FALSE; #endif /* First check that we haven't called match() too many times, or that we haven't exceeded the recursive call limit. */ if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT); /* At the start of a group with an unlimited repeat that may match an empty string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is done this way to save having to use another function argument, which would take up space on the stack. See also MATCH_CONDASSERT below. When MATCH_CBEGROUP is set, add the current subject pointer to the chain of such remembered pointers, to be checked when we hit the closing ket, in order to break infinite loops that match no characters. When match() is called in other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must NOT be used with tail recursion, because the memory block that is used is on the stack, so a new one may be required for each match(). */ if (md->match_function_type == MATCH_CBEGROUP) { newptrb.epb_saved_eptr = eptr; newptrb.epb_prev = eptrb; eptrb = &newptrb; md->match_function_type = 0; } /* Now start processing the opcodes. */ for (;;) { minimize = possessive = FALSE; op = *ecode; switch(op) { case OP_MARK: md->nomatch_mark = ecode + 2; md->mark = NULL; /* In case previously set by assertion */ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, eptrb, RM55); if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && md->mark == NULL) md->mark = ecode + 2; /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an argument, and we must check whether that argument matches this MARK's argument. It is passed back in md->start_match_ptr (an overloading of that variable). If it does match, we reset that variable to the current subject position and return MATCH_SKIP. Otherwise, pass back the return code unaltered. */ else if (rrc == MATCH_SKIP_ARG && STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0) { md->start_match_ptr = eptr; RRETURN(MATCH_SKIP); } RRETURN(rrc); case OP_FAIL: RRETURN(MATCH_NOMATCH); /* COMMIT overrides PRUNE, SKIP, and THEN */ case OP_COMMIT: RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM52); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG && rrc != MATCH_THEN) RRETURN(rrc); RRETURN(MATCH_COMMIT); /* PRUNE overrides THEN */ case OP_PRUNE: RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM51); if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); RRETURN(MATCH_PRUNE); case OP_PRUNE_ARG: md->nomatch_mark = ecode + 2; md->mark = NULL; /* In case previously set by assertion */ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, eptrb, RM56); if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && md->mark == NULL) md->mark = ecode + 2; if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); RRETURN(MATCH_PRUNE); /* SKIP overrides PRUNE and THEN */ case OP_SKIP: RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM53); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) RRETURN(rrc); md->start_match_ptr = eptr; /* Pass back current position */ RRETURN(MATCH_SKIP); /* Note that, for Perl compatibility, SKIP with an argument does NOT set nomatch_mark. There is a flag that disables this opcode when re-matching a pattern that ended with a SKIP for which there was not a matching MARK. */ case OP_SKIP_ARG: if (md->ignore_skip_arg) { ecode += PRIV(OP_lengths)[*ecode] + ecode[1]; break; } RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, eptrb, RM57); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) RRETURN(rrc); /* Pass back the current skip name by overloading md->start_match_ptr and returning the special MATCH_SKIP_ARG return code. This will either be caught by a matching MARK, or get to the top, where it causes a rematch with the md->ignore_skip_arg flag set. */ md->start_match_ptr = ecode + 2; RRETURN(MATCH_SKIP_ARG); /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that the branch in which it occurs can be determined. Overload the start of match pointer to do this. */ case OP_THEN: RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM54); if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->start_match_ptr = ecode; RRETURN(MATCH_THEN); case OP_THEN_ARG: md->nomatch_mark = ecode + 2; md->mark = NULL; /* In case previously set by assertion */ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, eptrb, RM58); if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && md->mark == NULL) md->mark = ecode + 2; if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->start_match_ptr = ecode; RRETURN(MATCH_THEN); /* Handle an atomic group that does not contain any capturing parentheses. This can be handled like an assertion. Prior to 8.13, all atomic groups were handled this way. In 8.13, the code was changed as below for ONCE, so that backups pass through the group and thereby reset captured values. However, this uses a lot more stack, so in 8.20, atomic groups that do not contain any captures generate OP_ONCE_NC, which can be handled in the old, less stack intensive way. Check the alternative branches in turn - the matching won't pass the KET for this kind of subpattern. If any one branch matches, we carry on as at the end of a normal bracket, leaving the subject pointer, but resetting the start-of-match value in case it was changed by \K. */ case OP_ONCE_NC: prev = ecode; saved_eptr = eptr; save_mark = md->mark; do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64); if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */ { mstart = md->start_match_ptr; break; } if (rrc == MATCH_THEN) { next = ecode + GET(ecode,1); if (md->start_match_ptr < next && (*ecode == OP_ALT || *next == OP_ALT)) rrc = MATCH_NOMATCH; } if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode,1); md->mark = save_mark; } while (*ecode == OP_ALT); /* If hit the end of the group (which could be repeated), fail */ if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); /* Continue as from after the group, updating the offsets high water mark, since extracts may have been taken. */ do ecode += GET(ecode, 1); while (*ecode == OP_ALT); 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 (*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 second "call" of match() uses tail recursion, to avoid using another stack frame. */ if (*ecode == OP_KETRMIN) { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode = prev; goto TAIL_RECURSE; } else /* OP_KETRMAX */ { RMATCH(eptr, prev, offset_top, md, eptrb, RM66); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += 1 + LINK_SIZE; goto TAIL_RECURSE; } /* Control never gets here */ /* Handle a capturing bracket, other than those that are possessive with an unlimited repeat. If there is space in the offset vector, save the current subject position in the working slot at the top of the vector. We mustn't change the current values of the data slot, because they may be set from a previous iteration of this group, and be referred to by a reference inside the group. A failure to match might occur after the group has succeeded, if something later on doesn't match. For this reason, we need to restore the working value and also the values of the final offsets, in case they were set by a previous iteration of the same bracket. If there isn't enough space in the offset vector, treat this as if it were a non-capturing bracket. Don't worry about setting the flag for the error case here; that is handled in the code for KET. */ case OP_CBRA: case OP_SCBRA: number = GET2(ecode, 1+LINK_SIZE); offset = number << 1; #ifdef PCRE_DEBUG printf("start bracket %d\n", number); printf("subject="); pchars(eptr, 16, TRUE, md); printf("\n"); #endif if (offset < md->offset_max) { save_offset1 = md->offset_vector[offset]; save_offset2 = md->offset_vector[offset+1]; save_offset3 = md->offset_vector[md->offset_end - number]; save_capture_last = md->capture_last; save_mark = md->mark; DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); md->offset_vector[md->offset_end - number] = (int)(eptr - md->start_subject); for (;;) { if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM1); if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ /* If we backed up to a THEN, check whether it is within the current branch by comparing the address of the THEN that is passed back with the end of the branch. If it is within the current branch, and the branch is one of two or more alternatives (it either starts or ends with OP_ALT), we have reached the limit of THEN's action, so convert the return code to NOMATCH, which will cause normal backtracking to happen from now on. Otherwise, THEN is passed back to an outer alternative. This implements Perl's treatment of parenthesized groups, where a group not containing | does not affect the current alternative, that is, (X) is NOT the same as (X|(*F)). */ if (rrc == MATCH_THEN) { next = ecode + GET(ecode,1); if (md->start_match_ptr < next && (*ecode == OP_ALT || *next == OP_ALT)) rrc = MATCH_NOMATCH; } /* Anything other than NOMATCH is passed back. */ if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->capture_last = save_capture_last; ecode += GET(ecode, 1); md->mark = save_mark; if (*ecode != OP_ALT) break; } DPRINTF(("bracket %d failed\n", number)); md->offset_vector[offset] = save_offset1; md->offset_vector[offset+1] = save_offset2; md->offset_vector[md->offset_end - number] = save_offset3; /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */ RRETURN(rrc); } /* FALL THROUGH ... Insufficient room for saving captured contents. Treat as a non-capturing bracket. */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ DPRINTF(("insufficient capture room: treat as non-capturing\n")); /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* Non-capturing or atomic group, except for possessive with unlimited repeat and ONCE group with no captures. Loop for all the alternatives. When we get to the final alternative within the brackets, we used to return the result of a recursive call to match() whatever happened so it was possible to reduce stack usage by turning this into a tail recursion, except in the case of a possibly empty group. However, now that there is the possiblity of (*THEN) occurring in the final alternative, this optimization is no longer always possible. We can optimize if we know there are no (*THEN)s in the pattern; at present this is the best that can be done. MATCH_ONCE is returned when the end of an atomic group is successfully reached, but subsequent matching fails. It passes back up the tree (causing captured values to be reset) until the original atomic group level is reached. This is tested by comparing md->once_target with the start of the group. At this point, the return is converted into MATCH_NOMATCH so that previous backup points can be taken. */ case OP_ONCE: case OP_BRA: case OP_SBRA: DPRINTF(("start non-capturing bracket\n")); for (;;) { if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP; /* If this is not a possibly empty group, and there are no (*THEN)s in the pattern, and this is the final alternative, optimize as described above. */ else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT) { ecode += PRIV(OP_lengths)[*ecode]; goto TAIL_RECURSE; } /* In all other cases, we have to make another call to match(). */ save_mark = md->mark; RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM2); /* See comment in the code for capturing groups above about handling THEN. */ if (rrc == MATCH_THEN) { next = ecode + GET(ecode,1); if (md->start_match_ptr < next && (*ecode == OP_ALT || *next == OP_ALT)) rrc = MATCH_NOMATCH; } if (rrc != MATCH_NOMATCH) { if (rrc == MATCH_ONCE) { const pcre_uchar *scode = ecode; if (*scode != OP_ONCE) /* If not at start, find it */ { while (*scode == OP_ALT) scode += GET(scode, 1); scode -= GET(scode, 1); } if (md->once_target == scode) rrc = MATCH_NOMATCH; } RRETURN(rrc); } ecode += GET(ecode, 1); md->mark = save_mark; if (*ecode != OP_ALT) break; } RRETURN(MATCH_NOMATCH); /* Handle possessive capturing brackets with an unlimited repeat. We come here from BRAZERO with allow_zero set TRUE. The offset_vector values are handled similarly to the normal case above. However, the matching is different. The end of these brackets will always be OP_KETRPOS, which returns MATCH_KETRPOS without going further in the pattern. By this means we can handle the group by iteration rather than recursion, thereby reducing the amount of stack needed. */ case OP_CBRAPOS: case OP_SCBRAPOS: allow_zero = FALSE; POSSESSIVE_CAPTURE: number = GET2(ecode, 1+LINK_SIZE); offset = number << 1; #ifdef PCRE_DEBUG printf("start possessive bracket %d\n", number); printf("subject="); pchars(eptr, 16, TRUE, md); printf("\n"); #endif if (offset < md->offset_max) { matched_once = FALSE; code_offset = (int)(ecode - md->start_code); save_offset1 = md->offset_vector[offset]; save_offset2 = md->offset_vector[offset+1]; save_offset3 = md->offset_vector[md->offset_end - number]; save_capture_last = md->capture_last; DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); /* Each time round the loop, save the current subject position for use when the group matches. For MATCH_MATCH, the group has matched, so we restart it with a new subject starting position, remembering that we had at least one match. For MATCH_NOMATCH, carry on with the alternatives, as usual. If we haven't matched any alternatives in any iteration, check to see if a previous iteration matched. If so, the group has matched; continue from afterwards. Otherwise it has failed; restore the previous capture values before returning NOMATCH. */ for (;;) { md->offset_vector[md->offset_end - number] = (int)(eptr - md->start_subject); if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM63); if (rrc == MATCH_KETRPOS) { offset_top = md->end_offset_top; eptr = md->end_match_ptr; ecode = md->start_code + code_offset; save_capture_last = md->capture_last; matched_once = TRUE; continue; } /* See comment in the code for capturing groups above about handling THEN. */ if (rrc == MATCH_THEN) { next = ecode + GET(ecode,1); if (md->start_match_ptr < next && (*ecode == OP_ALT || *next == OP_ALT)) rrc = MATCH_NOMATCH; } if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->capture_last = save_capture_last; ecode += GET(ecode, 1); if (*ecode != OP_ALT) break; } if (!matched_once) { md->offset_vector[offset] = save_offset1; md->offset_vector[offset+1] = save_offset2; md->offset_vector[md->offset_end - number] = save_offset3; } if (allow_zero || matched_once) { ecode += 1 + LINK_SIZE; break; } RRETURN(MATCH_NOMATCH); } /* FALL THROUGH ... Insufficient room for saving captured contents. Treat as a non-capturing bracket. */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ DPRINTF(("insufficient capture room: treat as non-capturing\n")); /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* Non-capturing possessive bracket with unlimited repeat. We come here from BRAZERO with allow_zero = TRUE. The code is similar to the above, without the capturing complication. It is written out separately for speed and cleanliness. */ case OP_BRAPOS: case OP_SBRAPOS: allow_zero = FALSE; POSSESSIVE_NON_CAPTURE: matched_once = FALSE; code_offset = (int)(ecode - md->start_code); for (;;) { if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM48); if (rrc == MATCH_KETRPOS) { offset_top = md->end_offset_top; eptr = md->end_match_ptr; ecode = md->start_code + code_offset; matched_once = TRUE; continue; } /* See comment in the code for capturing groups above about handling THEN. */ if (rrc == MATCH_THEN) { next = ecode + GET(ecode,1); if (md->start_match_ptr < next && (*ecode == OP_ALT || *next == OP_ALT)) rrc = MATCH_NOMATCH; } if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode, 1); if (*ecode != OP_ALT) break; } if (matched_once || allow_zero) { ecode += 1 + LINK_SIZE; break; } 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. */ case OP_COND: case OP_SCOND: codelink = GET(ecode, 1); /* Because of the way auto-callout works during compile, a callout item is inserted between OP_COND and an assertion condition. */ if (ecode[LINK_SIZE+1] == OP_CALLOUT) { if (PUBL(callout) != NULL) { PUBL(callout_block) cb; cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[LINK_SIZE+2]; cb.offset_vector = md->offset_vector; #ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; #else cb.subject = (PCRE_SPTR16)md->start_subject; #endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); cb.current_position = (int)(eptr - md->start_subject); cb.pattern_position = GET(ecode, LINK_SIZE + 3); cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE); cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; cb.mark = md->nomatch_mark; if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += PRIV(OP_lengths)[OP_CALLOUT]; } condcode = ecode[LINK_SIZE+1]; /* Now see what the actual condition is */ if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */ { if (md->recursive == NULL) /* Not recursing => FALSE */ { condition = FALSE; ecode += GET(ecode, 1); } else { int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ condition = (recno == RREF_ANY || recno == md->recursive->group_num); /* If the test is for recursion into a specific subpattern, and it is false, but the test was set up by name, scan the table to see if the name refers to any other numbers, and test them. The condition is true if any one is set. */ if (!condition && condcode == OP_NRREF) { pcre_uchar *slotA = md->name_table; for (i = 0; i < md->name_count; i++) { if (GET2(slotA, 0) == recno) break; slotA += md->name_entry_size; } /* Found a name for the number - there can be only one; duplicate names for different numbers are allowed, but not vice versa. First scan down for duplicates. */ if (i < md->name_count) { pcre_uchar *slotB = slotA; while (slotB > md->name_table) { slotB -= md->name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == md->recursive->group_num; if (condition) break; } else break; } /* Scan up for duplicates */ if (!condition) { slotB = slotA; for (i++; i < md->name_count; i++) { slotB += md->name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == md->recursive->group_num; if (condition) break; } else break; } } } } /* Chose branch according to the condition */ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); } } else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */ { offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */ condition = offset < offset_top && md->offset_vector[offset] >= 0; /* If the numbered capture is unset, but the reference was by name, scan the table to see if the name refers to any other numbers, and test them. The condition is true if any one is set. This is tediously similar to the code above, but not close enough to try to amalgamate. */ if (!condition && condcode == OP_NCREF) { int refno = offset >> 1; pcre_uchar *slotA = md->name_table; for (i = 0; i < md->name_count; i++) { if (GET2(slotA, 0) == refno) break; slotA += md->name_entry_size; } /* Found a name for the number - there can be only one; duplicate names for different numbers are allowed, but not vice versa. First scan down for duplicates. */ if (i < md->name_count) { pcre_uchar *slotB = slotA; while (slotB > md->name_table) { slotB -= md->name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { offset = GET2(slotB, 0) << 1; condition = offset < offset_top && md->offset_vector[offset] >= 0; if (condition) break; } else break; } /* Scan up for duplicates */ if (!condition) { slotB = slotA; for (i++; i < md->name_count; i++) { slotB += md->name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { offset = GET2(slotB, 0) << 1; condition = offset < offset_top && md->offset_vector[offset] >= 0; if (condition) break; } else break; } } } } /* Chose branch according to the condition */ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); } else if (condcode == OP_DEF) /* DEFINE - always false */ { condition = FALSE; ecode += GET(ecode, 1); } /* The condition is an assertion. Call match() to evaluate it - setting md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of an assertion. */ else { md->match_function_type = MATCH_CONDASSERT; RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3); if (rrc == MATCH_MATCH) { if (md->end_offset_top > offset_top) offset_top = md->end_offset_top; /* Captures may have happened */ condition = TRUE; ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2); while (*ecode == OP_ALT) ecode += GET(ecode, 1); } /* PCRE doesn't allow the effect of (*THEN) to escape beyond an assertion; it is therefore treated as NOMATCH. */ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) { RRETURN(rrc); /* Need braces because of following else */ } else { condition = FALSE; ecode += codelink; } } /* We are now at the branch that is to be obeyed. As there is only one, can use tail recursion to avoid using another stack frame, except when there is unlimited repeat of a possibly empty group. In the latter case, a recursive call to match() is always required, unless the second alternative doesn't exist, in which case we can just plough on. Note that, for compatibility with Perl, the | in a conditional group is NOT treated as creating two alternatives. If a THEN is encountered in the branch, it propagates out to the enclosing alternative (unless nested in a deeper set of alternatives, of course). */ if (condition || *ecode == OP_ALT) { if (op != OP_SCOND) { ecode += 1 + LINK_SIZE; goto TAIL_RECURSE; } md->match_function_type = MATCH_CBEGROUP; RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49); RRETURN(rrc); } /* Condition false & no alternative; continue after the group. */ else { ecode += 1 + LINK_SIZE; } break; /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, to close any currently open capturing brackets. */ case OP_CLOSE: number = GET2(ecode, 1); offset = number << 1; #ifdef PCRE_DEBUG printf("end bracket %d at *ACCEPT", number); printf("\n"); #endif 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] = (int)(eptr - md->start_subject); if (offset_top <= offset) offset_top = offset + 2; } ecode += 1 + IMM2_SIZE; break; /* End of the pattern, either real or forced. */ case OP_END: case OP_ACCEPT: case OP_ASSERT_ACCEPT: /* If we have matched an empty string, fail if not in an assertion and not in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of the subject. In both cases, backtracking will then try other alternatives, if any. */ if (eptr == mstart && op != OP_ASSERT_ACCEPT && md->recursive == NULL && (md->notempty || (md->notempty_atstart && mstart == md->start_subject + md->start_offset))) RRETURN(MATCH_NOMATCH); /* Otherwise, we have a match. */ md->end_match_ptr = eptr; /* Record where we ended */ md->end_offset_top = offset_top; /* and how many extracts were taken */ md->start_match_ptr = mstart; /* and the start (\K can modify) */ /* For some reason, the macros don't work properly if an expression is given as the argument to RRETURN when the heap is in use. */ rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT; RRETURN(rrc); /* Assertion brackets. Check the alternative branches in turn - the matching won't pass the KET for an assertion. If any one branch matches, the assertion is true. Lookbehind assertions have an OP_REVERSE item at the start of each branch to move the current point backwards, so the code at this level is identical to the lookahead case. When the assertion is part of a condition, we want to return immediately afterwards. The caller of this incarnation of the match() function will have set MATCH_CONDASSERT in md->match_function type, and one of these opcodes will be the first opcode that is processed. We use a local variable that is preserved over calls to match() to remember this case. */ case OP_ASSERT: case OP_ASSERTBACK: save_mark = md->mark; if (md->match_function_type == MATCH_CONDASSERT) { condassert = TRUE; md->match_function_type = 0; } else condassert = FALSE; do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4); if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { mstart = md->start_match_ptr; /* In case \K reset it */ break; } md->mark = save_mark; /* A COMMIT failure must fail the entire assertion, without trying any subsequent branches. */ if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH); /* PCRE does not allow THEN to escape beyond an assertion; it is treated as NOMATCH. */ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode, 1); } while (*ecode == OP_ALT); if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); /* If checking an assertion for a condition, return MATCH_MATCH. */ if (condassert) RRETURN(MATCH_MATCH); /* Continue from after the assertion, updating the offsets high water mark, since extracts may have been taken during the assertion. */ do ecode += GET(ecode,1); while (*ecode == OP_ALT); ecode += 1 + LINK_SIZE; offset_top = md->end_offset_top; continue; /* Negative assertion: all branches must fail to match. Encountering SKIP, PRUNE, or COMMIT means we must assume failure without checking subsequent branches. */ case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: save_mark = md->mark; if (md->match_function_type == MATCH_CONDASSERT) { condassert = TRUE; md->match_function_type = 0; } else condassert = FALSE; do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); md->mark = save_mark; if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) { do ecode += GET(ecode,1); while (*ecode == OP_ALT); break; } /* PCRE does not allow THEN to escape beyond an assertion; it is treated as NOMATCH. */ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ ecode += 1 + LINK_SIZE; continue; /* Move the subject pointer back. This occurs only at the start of each branch of a lookbehind assertion. If we are too close to the start to move back, this match function fails. When working with UTF-8 we move back a number of characters, not bytes. */ case OP_REVERSE: #ifdef SUPPORT_UTF if (utf) { i = GET(ecode, 1); while (i-- > 0) { eptr--; if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); BACKCHAR(eptr); } } else #endif /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ { eptr -= GET(ecode, 1); if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); } /* Save the earliest consulted character, then skip to next op code */ if (eptr < md->start_used_ptr) md->start_used_ptr = eptr; ecode += 1 + LINK_SIZE; break; /* The callout item calls an external function, if one is provided, passing details of the match so far. This is mainly for debugging, though the function is able to force a failure. */ case OP_CALLOUT: if (PUBL(callout) != NULL) { PUBL(callout_block) cb; cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; #ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; #else cb.subject = (PCRE_SPTR16)md->start_subject; #endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); cb.current_position = (int)(eptr - md->start_subject); cb.pattern_position = GET(ecode, 2); cb.next_item_length = GET(ecode, 2 + LINK_SIZE); cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; cb.mark = md->nomatch_mark; if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += 2 + 2*LINK_SIZE; break; /* Recursion either matches the current regex, or some subexpression. The offset data is the offset to the starting bracket from the start of the whole pattern. (This is so that it works from duplicated subpatterns.) The state of the capturing groups is preserved over recursion, and re-instated afterwards. We don't know how many are started and not yet finished (offset_top records the completed total) so we just have to save all the potential data. There may be up to 65535 such values, which is too large to put on the stack, but using malloc for small numbers seems expensive. As a compromise, the stack is used when there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc is used. There are also other values that have to be saved. We use a chained sequence of blocks that actually live on the stack. Thanks to Robin Houston for the original version of this logic. It has, however, been hacked around a lot, so he is not to blame for the current way it works. */ case OP_RECURSE: { recursion_info *ri; int recno; callpat = md->start_code + GET(ecode, 1); recno = (callpat == md->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); /* Check for repeating a recursion without advancing the subject pointer. This should catch convoluted mutual recursions. (Some simple cases are caught at compile time.) */ for (ri = md->recursive; ri != NULL; ri = ri->prevrec) if (recno == ri->group_num && eptr == ri->subject_position) RRETURN(PCRE_ERROR_RECURSELOOP); /* Add to "recursing stack" */ new_recursive.group_num = recno; new_recursive.subject_position = eptr; new_recursive.prevrec = md->recursive; md->recursive = &new_recursive; /* Where to continue from afterwards */ ecode += 1 + LINK_SIZE; /* Now save the offset data */ new_recursive.saved_max = md->offset_end; if (new_recursive.saved_max <= REC_STACK_SAVE_MAX) new_recursive.offset_save = stacksave; else { new_recursive.offset_save = (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int)); if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); } memcpy(new_recursive.offset_save, md->offset_vector, new_recursive.saved_max * sizeof(int)); /* OK, now we can do the recursion. After processing each alternative, restore the offset data. If there were nested recursions, md->recursive might be changed, so reset it before looping. */ DPRINTF(("Recursing into group %d\n", new_recursive.group_num)); cbegroup = (*callpat >= OP_SBRA); do { if (cbegroup) md->match_function_type = MATCH_CBEGROUP; RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top, md, eptrb, RM6); memcpy(md->offset_vector, new_recursive.offset_save, new_recursive.saved_max * sizeof(int)); md->recursive = new_recursive.prevrec; if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { DPRINTF(("Recursion matched\n")); if (new_recursive.offset_save != stacksave) (PUBL(free))(new_recursive.offset_save); /* Set where we got to in the subject, and reset the start in case it was changed by \K. This *is* propagated back out of a recursion, for Perl compatibility. */ eptr = md->end_match_ptr; mstart = md->start_match_ptr; goto RECURSION_MATCHED; /* Exit loop; end processing */ } /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it is treated as NOMATCH. */ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN && rrc != MATCH_COMMIT) { DPRINTF(("Recursion gave error %d\n", rrc)); if (new_recursive.offset_save != stacksave) (PUBL(free))(new_recursive.offset_save); RRETURN(rrc); } md->recursive = &new_recursive; callpat += GET(callpat, 1); } while (*callpat == OP_ALT); DPRINTF(("Recursion didn't match\n")); md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) (PUBL(free))(new_recursive.offset_save); RRETURN(MATCH_NOMATCH); } RECURSION_MATCHED: break; /* An alternation is the end of a branch; scan along to find the end of the bracketed group and go to there. */ case OP_ALT: do ecode += GET(ecode,1); while (*ecode == OP_ALT); break; /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group, indicating that it may occur zero times. It may repeat infinitely, or not at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets with fixed upper repeat limits are compiled as a number of copies, with the optional ones preceded by BRAZERO or BRAMINZERO. */ case OP_BRAZERO: next = ecode + 1; RMATCH(eptr, next, offset_top, md, eptrb, RM10); if (rrc != MATCH_NOMATCH) RRETURN(rrc); do next += GET(next, 1); while (*next == OP_ALT); ecode = next + 1 + LINK_SIZE; break; case OP_BRAMINZERO: next = ecode + 1; do next += GET(next, 1); while (*next == OP_ALT); RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode++; break; case OP_SKIPZERO: next = ecode+1; do next += GET(next,1); while (*next == OP_ALT); ecode = next + 1 + LINK_SIZE; break; /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything here; just jump to the group, with allow_zero set TRUE. */ case OP_BRAPOSZERO: op = *(++ecode); allow_zero = TRUE; if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE; goto POSSESSIVE_NON_CAPTURE; /* End of a group, repeated or non-repeating. */ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: case OP_KETRPOS: prev = ecode - GET(ecode, 1); /* If this was a group that remembered the subject start, in order to break infinite repeats of empty string matches, retrieve the subject start from the chain. Otherwise, set it NULL. */ if (*prev >= OP_SBRA || *prev == OP_ONCE) { saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */ eptrb = eptrb->epb_prev; /* Backup to previous group */ } else saved_eptr = NULL; /* If we are at the end of an assertion group or a non-capturing atomic group, stop matching and return MATCH_MATCH, but record the current high water mark for use by positive assertions. We also need to record the match start in case it was changed by \K. */ if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) || *prev == OP_ONCE_NC) { md->end_match_ptr = eptr; /* For ONCE_NC */ md->end_offset_top = offset_top; md->start_match_ptr = mstart; RRETURN(MATCH_MATCH); /* Sets md->mark */ } /* For capturing groups 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. 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. Other recursion is handled here. We just have to record the current subject position and start match pointer and give a MATCH return. */ if (*prev == OP_CBRA || *prev == OP_SCBRA || *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS) { number = GET2(prev, 1+LINK_SIZE); offset = number << 1; #ifdef PCRE_DEBUG printf("end bracket %d", number); printf("\n"); #endif /* Handle a recursively called group. */ if (md->recursive != NULL && md->recursive->group_num == number) { md->end_match_ptr = eptr; md->start_match_ptr = mstart; RRETURN(MATCH_MATCH); } /* Deal with capturing */ md->capture_last = number; if (offset >= md->offset_max) md->offset_overflow = TRUE; else { /* If offset is greater than offset_top, it means that we are "skipping" a capturing group, and that group's offsets must be marked unset. In earlier versions of PCRE, all the offsets were unset at the start of matching, but this doesn't work because atomic groups and assertions can cause a value to be set that should later be unset. Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as part of the atomic group, but this is not on the final matching path, so must be unset when 2 is set. (If there is no group 2, there is no problem, because offset_top will then be 2, indicating no capture.) */ if (offset > offset_top) { register int *iptr = md->offset_vector + offset_top; register int *iend = md->offset_vector + offset; while (iptr < iend) *iptr++ = -1; } /* Now make the extraction */ md->offset_vector[offset] = md->offset_vector[md->offset_end - number]; md->offset_vector[offset+1] = (int)(eptr - md->start_subject); if (offset_top <= offset) offset_top = offset + 2; } } /* For an ordinary 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. For a non-repeating atomic group that includes captures, establish a backup point by processing the rest of the pattern at a lower level. If this results in a NOMATCH return, pass MATCH_ONCE back to the original OP_ONCE level, thereby bypassing intermediate backup points, but resetting any captures that happened along the way. */ if (*ecode == OP_KET || eptr == saved_eptr) { if (*prev == OP_ONCE) { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12); if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ RRETURN(MATCH_ONCE); } ecode += 1 + LINK_SIZE; /* Carry on at this level */ break; } /* OP_KETRPOS is a possessive repeating ket. Remember the current position, and return the MATCH_KETRPOS. This makes it possible to do the repeats one at a time from the outer level, thus saving stack. */ if (*ecode == OP_KETRPOS) { md->end_match_ptr = eptr; md->end_offset_top = offset_top; RRETURN(MATCH_KETRPOS); } /* The normal 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, unless we have an an atomic group or an unlimited repeat of a group that can match an empty string. */ if (*ecode == OP_KETRMIN) { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (*prev == OP_ONCE) { RMATCH(eptr, prev, offset_top, md, eptrb, RM8); if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ RRETURN(MATCH_ONCE); } if (*prev >= OP_SBRA) /* Could match an empty string */ { RMATCH(eptr, prev, offset_top, md, eptrb, RM50); RRETURN(rrc); } ecode = prev; goto TAIL_RECURSE; } else /* OP_KETRMAX */ { RMATCH(eptr, prev, offset_top, md, eptrb, RM13); if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH; if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (*prev == OP_ONCE) { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9); if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->once_target = prev; RRETURN(MATCH_ONCE); } ecode += 1 + LINK_SIZE; goto TAIL_RECURSE; } /* Control never gets here */ /* Not multiline mode: start of subject assertion, unless notbol. */ case OP_CIRC: if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); /* Start of subject assertion */ case OP_SOD: if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH); ecode++; break; /* Multiline mode: start of subject unless notbol, or after any newline. */ case OP_CIRCM: if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); if (eptr != md->start_subject && (eptr == md->end_subject || !WAS_NEWLINE(eptr))) RRETURN(MATCH_NOMATCH); ecode++; break; /* Start of match assertion */ case OP_SOM: if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); ecode++; break; /* Reset the start of match point */ case OP_SET_SOM: mstart = eptr; ecode++; break; /* Multiline mode: assert before any newline, or before end of subject unless noteol is set. */ case OP_DOLLM: if (eptr < md->end_subject) { if (!IS_NEWLINE(eptr)) { if (md->partial != 0 && eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } RRETURN(MATCH_NOMATCH); } } else { if (md->noteol) RRETURN(MATCH_NOMATCH); SCHECK_PARTIAL(); } ecode++; break; /* Not multiline mode: assert before a terminating newline or before end of subject unless noteol is set. */ case OP_DOLL: if (md->noteol) RRETURN(MATCH_NOMATCH); if (!md->endonly) goto ASSERT_NL_OR_EOS; /* ... else fall through for endonly */ /* End of subject assertion (\z) */ case OP_EOD: if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH); SCHECK_PARTIAL(); ecode++; break; /* End of subject or ending \n assertion (\Z) */ case OP_EODN: ASSERT_NL_OR_EOS: if (eptr < md->end_subject && (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) { if (md->partial != 0 && eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } RRETURN(MATCH_NOMATCH); } /* Either at end of string or \n before end. */ SCHECK_PARTIAL(); ecode++; break; /* Word boundary assertions */ case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: { /* Find out if the previous and current characters are "word" characters. It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to be "non-word" characters. Remember the earliest consulted character for partial matching. */ #ifdef SUPPORT_UTF if (utf) { /* Get status of previous character */ if (eptr == md->start_subject) prev_is_word = FALSE; else { PCRE_PUCHAR lastptr = eptr - 1; BACKCHAR(lastptr); if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr; GETCHAR(c, lastptr); #ifdef SUPPORT_UCP if (md->use_ucp) { if (c == '_') prev_is_word = TRUE; else { int cat = UCD_CATEGORY(c); prev_is_word = (cat == ucp_L || cat == ucp_N); } } else #endif prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; } /* Get status of next character */ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); cur_is_word = FALSE; } else { GETCHAR(c, eptr); #ifdef SUPPORT_UCP if (md->use_ucp) { if (c == '_') cur_is_word = TRUE; else { int cat = UCD_CATEGORY(c); cur_is_word = (cat == ucp_L || cat == ucp_N); } } else #endif cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; } } else #endif /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for consistency with the behaviour of \w we do use it in this case. */ { /* Get status of previous character */ if (eptr == md->start_subject) prev_is_word = FALSE; else { if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1; #ifdef SUPPORT_UCP if (md->use_ucp) { c = eptr[-1]; if (c == '_') prev_is_word = TRUE; else { int cat = UCD_CATEGORY(c); prev_is_word = (cat == ucp_L || cat == ucp_N); } } else #endif prev_is_word = MAX_255(eptr[-1]) && ((md->ctypes[eptr[-1]] & ctype_word) != 0); } /* Get status of next character */ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); cur_is_word = FALSE; } else #ifdef SUPPORT_UCP if (md->use_ucp) { c = *eptr; if (c == '_') cur_is_word = TRUE; else { int cat = UCD_CATEGORY(c); cur_is_word = (cat == ucp_L || cat == ucp_N); } } else #endif cur_is_word = MAX_255(*eptr) && ((md->ctypes[*eptr] & ctype_word) != 0); } /* Now see if the situation is what we want */ if ((*ecode++ == OP_WORD_BOUNDARY)? cur_is_word == prev_is_word : cur_is_word != prev_is_word) RRETURN(MATCH_NOMATCH); } break; /* Match any single character type except newline; have to take care with CRLF newlines and partial matching. */ case OP_ANY: if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); if (md->partial != 0 && eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } /* Fall through */ /* Match any single character whatsoever. */ case OP_ALLANY: if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ { /* not be updated before SCHECK_PARTIAL. */ SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr++; #ifdef SUPPORT_UTF if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); #endif ecode++; break; /* Match a single byte, even in UTF-8 mode. This opcode really does match any byte, even newline, independent of the setting of PCRE_DOTALL. */ case OP_ANYBYTE: if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ { /* not be updated before SCHECK_PARTIAL. */ SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr++; ecode++; break; case OP_NOT_DIGIT: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_digit) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_DIGIT: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c > 255 || #endif (md->ctypes[c] & ctype_digit) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_WHITESPACE: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_space) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_WHITESPACE: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c > 255 || #endif (md->ctypes[c] & ctype_space) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_WORDCHAR: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_word) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_WORDCHAR: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c > 255 || #endif (md->ctypes[c] & ctype_word) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_ANYNL: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); } else if (*eptr == 0x0a) eptr++; break; case 0x000a: break; case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } ecode++; break; case OP_NOT_HSPACE: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ RRETURN(MATCH_NOMATCH); } ecode++; break; case OP_HSPACE: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; } ecode++; break; case OP_NOT_VSPACE: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ RRETURN(MATCH_NOMATCH); } ecode++; break; case OP_VSPACE: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ break; } ecode++; break; #ifdef SUPPORT_UCP /* Check the next character by Unicode property. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ case OP_PROP: case OP_NOTPROP: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); { const ucd_record *prop = GET_UCD(c); switch(ecode[1]) { case PT_ANY: if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); break; case PT_LAMP: if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt) == (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); break; case PT_GC: if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); break; case PT_PC: if ((ecode[2] != prop->chartype) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); break; case PT_SC: if ((ecode[2] != prop->script) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); break; /* These are specials */ case PT_ALNUM: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); break; case PT_SPACE: /* Perl space */ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); break; case PT_PXSPACE: /* POSIX space */ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); break; case PT_WORD: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); break; /* This should never occur */ default: RRETURN(PCRE_ERROR_INTERNAL); } ecode += 3; } break; /* Match an extended Unicode sequence. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ case OP_EXTUNI: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } CHECK_PARTIAL(); ecode++; break; #endif /* Match a back reference, possibly repeatedly. Look past the end of the item to see if there is repeat information following. The code is similar to that for character classes, but repeated for efficiency. Then obey similar code to character type repeats - written out again for speed. However, if the referenced string is the empty string, always treat it as matched, any number of times (otherwise there could be infinite loops). */ case OP_REF: case OP_REFI: caseless = op == OP_REFI; offset = GET2(ecode, 1) << 1; /* Doubled ref number */ ecode += 1 + IMM2_SIZE; /* If the reference is unset, there are two possibilities: (a) In the default, Perl-compatible state, set the length negative; this ensures that every attempt at a match fails. We can't just fail here, because of the possibility of quantifiers with zero minima. (b) If the JavaScript compatibility flag is set, set the length to zero so that the back reference matches an empty string. Otherwise, set the length to the length of what was matched by the referenced subpattern. */ if (offset >= offset_top || md->offset_vector[offset] < 0) length = (md->jscript_compat)? 0 : -1; else length = md->offset_vector[offset+1] - md->offset_vector[offset]; /* Set up for repetition, or handle the non-repeated case */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; ecode += 1 + 2 * IMM2_SIZE; break; default: /* No repeat follows */ if ((length = match_ref(offset, eptr, length, md, caseless)) < 0) { if (length == -2) eptr = md->end_subject; /* Partial match */ CHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr += length; continue; /* With the main loop */ } /* Handle repeated back references. If the length of the reference is zero, just continue with the main loop. If the length is negative, it means the reference is unset in non-Java-compatible mode. If the minimum is zero, we can continue at the same level without recursion. For any other minimum, carrying on will result in NOMATCH. */ if (length == 0) continue; if (length < 0 && min == 0) continue; /* First, ensure the minimum number of matches are present. We get back the length of the reference string explicitly rather than passing the address of eptr, so that eptr can be a register variable. */ for (i = 1; i <= min; i++) { int slength; if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { if (slength == -2) eptr = md->end_subject; /* Partial match */ CHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr += slength; } /* If min = max, continue at the same level without recursion. They are not both allowed to be zero. */ if (min == max) continue; /* If minimizing, keep trying and advancing the pointer */ if (minimize) { for (fi = min;; fi++) { int slength; RMATCH(eptr, ecode, offset_top, md, eptrb, RM14); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { if (slength == -2) eptr = md->end_subject; /* Partial match */ CHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr += slength; } /* Control never gets here */ } /* If maximizing, find the longest string and work backwards */ else { pp = eptr; for (i = min; i < max; i++) { int slength; if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { /* Can't use CHECK_PARTIAL because we don't want to update eptr in the soft partial matching case. */ if (slength == -2 && md->partial != 0 && md->end_subject > md->start_used_ptr) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } break; } eptr += slength; } while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM15); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr -= length; } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ /* Match a bit-mapped character class, possibly repeatedly. This op code is used when all the characters in the class have values in the range 0-255, and either the matching is caseful, or the characters are in the range 0-127 when UTF-8 processing is enabled. The only difference between OP_CLASS and OP_NCLASS occurs when a data character outside the range is encountered. First, look past the end of the item to see if there is repeat information following. Then obey similar code to character type repeats - written out again for speed. */ case OP_NCLASS: case OP_CLASS: { /* The data variable is saved across frames, so the byte map needs to be stored there. */ #define BYTE_MAP ((pcre_uint8 *)data) data = ecode + 1; /* Save for matching */ ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; ecode += 1 + 2 * IMM2_SIZE; break; default: /* No repeat follows */ min = max = 1; break; } /* First, ensure the minimum number of matches are present. */ #ifdef SUPPORT_UTF if (utf) { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } c = *eptr++; #ifndef COMPILE_PCRE8 if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else #endif if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* If max == min we can continue with the main loop without the need to recurse. */ if (min == max) continue; /* If minimizing, keep testing the rest of the expression and advancing the pointer while it matches the class. */ if (minimize) { #ifdef SUPPORT_UTF if (utf) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM16); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM17); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } c = *eptr++; #ifndef COMPILE_PCRE8 if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else #endif if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ else { pp = eptr; #ifdef SUPPORT_UTF if (utf) { for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c > 255) { if (op == OP_CLASS) break; } else if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr += len; } for (;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM18); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } c = *eptr; #ifndef COMPILE_PCRE8 if (c > 255) { if (op == OP_CLASS) break; } else #endif if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr++; } while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM19); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } #undef BYTE_MAP } /* Control never gets here */ /* Match an extended character class. This opcode is encountered only when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8 mode, because Unicode properties are supported in non-UTF-8 mode. */ #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: { data = ecode + 1 + LINK_SIZE; /* Save for matching */ ecode += GET(ecode, 1); /* Advance past the item */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; ecode += 1 + 2 * IMM2_SIZE; break; default: /* No repeat follows */ min = max = 1; break; } /* First, ensure the minimum number of matches are present. */ for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); } /* If max == min we can continue with the main loop without the need to recurse. */ if (min == max) continue; /* If minimizing, keep testing the rest of the expression and advancing the pointer while it matches the class. */ if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM20); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ else { pp = eptr; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } #ifdef SUPPORT_UTF GETCHARLENTEST(c, eptr, len); #else c = *eptr; #endif if (!PRIV(xclass)(c, data, utf)) break; eptr += len; } for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM21); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ #ifdef SUPPORT_UTF if (utf) BACKCHAR(eptr); #endif } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } #endif /* End of XCLASS */ /* Match a single character, casefully */ case OP_CHAR: #ifdef SUPPORT_UTF if (utf) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); if (length > md->end_subject - eptr) { CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ RRETURN(MATCH_NOMATCH); } while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH); } else #endif /* Not UTF mode */ { if (md->end_subject - eptr < 1) { SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ RRETURN(MATCH_NOMATCH); } if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); ecode += 2; } break; /* Match a single character, caselessly. If we are at the end of the subject, give up immediately. */ case OP_CHARI: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } #ifdef SUPPORT_UTF if (utf) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); /* If the pattern character's value is < 128, we have only one byte, and we know that its other case must also be one byte long, so we can use the fast lookup table. We know that there is at least one byte left in the subject. */ if (fc < 128) { if (md->lcc[fc] != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); ecode++; eptr++; } /* Otherwise we must pick up the subject character. Note that we cannot use the value of "length" to check for sufficient bytes left, because the other case of the character may have more or fewer bytes. */ else { unsigned int dc; GETCHARINC(dc, eptr); ecode += length; /* If we have Unicode property support, we can use it to test the other case of the character, if there is one. */ if (fc != dc) { #ifdef SUPPORT_UCP if (dc != UCD_OTHERCASE(fc)) #endif RRETURN(MATCH_NOMATCH); } } } else #endif /* SUPPORT_UTF */ /* Not UTF mode */ { if (TABLE_GET(ecode[1], md->lcc, ecode[1]) != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); eptr++; ecode += 2; } break; /* Match a single character repeatedly. */ case OP_EXACT: case OP_EXACTI: min = max = GET2(ecode, 1); ecode += 1 + IMM2_SIZE; goto REPEATCHAR; case OP_POSUPTO: case OP_POSUPTOI: possessive = TRUE; /* Fall through */ case OP_UPTO: case OP_UPTOI: case OP_MINUPTO: case OP_MINUPTOI: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; ecode += 1 + IMM2_SIZE; goto REPEATCHAR; case OP_POSSTAR: case OP_POSSTARI: possessive = TRUE; min = 0; max = INT_MAX; ecode++; goto REPEATCHAR; case OP_POSPLUS: case OP_POSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; ecode++; goto REPEATCHAR; case OP_POSQUERY: case OP_POSQUERYI: possessive = TRUE; min = 0; max = 1; ecode++; goto REPEATCHAR; case OP_STAR: case OP_STARI: case OP_MINSTAR: case OP_MINSTARI: case OP_PLUS: case OP_PLUSI: case OP_MINPLUS: case OP_MINPLUSI: case OP_QUERY: case OP_QUERYI: case OP_MINQUERY: case OP_MINQUERYI: c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI); minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single-character matches. */ REPEATCHAR: #ifdef SUPPORT_UTF if (utf) { length = 1; charptr = ecode; GETCHARLEN(fc, ecode, length); ecode += length; /* Handle multibyte character matching specially here. There is support for caseless matching if UCP support is present. */ if (length > 1) { #ifdef SUPPORT_UCP unsigned int othercase; if (op >= OP_STARI && /* Caseless */ (othercase = UCD_OTHERCASE(fc)) != fc) oclength = PRIV(ord2utf)(othercase, occhars); else oclength = 0; #endif /* SUPPORT_UCP */ for (i = 1; i <= min; i++) { if (eptr <= md->end_subject - length && memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { CHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } } if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM22); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr <= md->end_subject - length && memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { CHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } else /* Maximize */ { pp = eptr; for (i = min; i < max; i++) { if (eptr <= md->end_subject - length && memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { CHECK_PARTIAL(); break; } } if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM23); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr == pp) { RRETURN(MATCH_NOMATCH); } #ifdef SUPPORT_UCP eptr--; BACKCHAR(eptr); #else /* without SUPPORT_UCP */ eptr -= length; #endif /* SUPPORT_UCP */ } } /* Control never gets here */ } /* If the length of a UTF-8 character is 1, we fall through here, and obey the code as for non-UTF-8 characters below, though in this case the value of fc will always be < 128. */ } else #endif /* SUPPORT_UTF */ /* When not in UTF-8 mode, load a single-byte character. */ fc = *ecode++; /* The value of fc at this point is always one character, though we may or may not be in UTF mode. The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if minimizing, keep trying the rest of the expression and advancing one matching character if failing, up to the maximum. Alternatively, if maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, (char *)eptr)); if (op >= OP_STARI) /* Caseless */ { #ifdef COMPILE_PCRE8 /* fc must be < 128 if UTF is enabled. */ foc = md->fcc[fc]; #else #ifdef SUPPORT_UTF #ifdef SUPPORT_UCP if (utf && fc > 127) foc = UCD_OTHERCASE(fc); #else if (utf && fc > 127) foc = fc; #endif /* SUPPORT_UCP */ else #endif /* SUPPORT_UTF */ foc = TABLE_GET(fc, md->fcc, fc); #endif /* COMPILE_PCRE8 */ for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); eptr++; } if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM24); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); eptr++; } /* Control never gets here */ } else /* Maximize */ { pp = eptr; for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (fc != *eptr && foc != *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM25); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* Caseful comparisons (includes all multi-byte characters) */ else { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM26); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } else /* Maximize */ { pp = eptr; for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (fc != *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM27); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a negated single one-byte character. The character we are checking can be multibyte. */ case OP_NOT: case OP_NOTI: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } #ifdef SUPPORT_UTF if (utf) { register unsigned int ch, och; ecode++; GETCHARINC(ch, ecode); GETCHARINC(c, eptr); if (op == OP_NOT) { if (ch == c) RRETURN(MATCH_NOMATCH); } else { #ifdef SUPPORT_UCP if (ch > 127) och = UCD_OTHERCASE(ch); #else if (ch > 127) och = ch; #endif /* SUPPORT_UCP */ else och = TABLE_GET(ch, md->fcc, ch); if (ch == c || och == c) RRETURN(MATCH_NOMATCH); } } else #endif { register unsigned int ch = ecode[1]; c = *eptr++; if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c)) RRETURN(MATCH_NOMATCH); ecode += 2; } break; /* Match a negated single one-byte character repeatedly. This is almost a repeat of the code for a repeated single character, but I haven't found a nice way of commoning these up that doesn't require a test of the positive/negative option for each character match. Maybe that wouldn't add very much to the time taken, but character matching *is* what this is all about... */ case OP_NOTEXACT: case OP_NOTEXACTI: min = max = GET2(ecode, 1); ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTUPTO: case OP_NOTUPTOI: case OP_NOTMINUPTO: case OP_NOTMINUPTOI: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTPOSSTAR: case OP_NOTPOSSTARI: possessive = TRUE; min = 0; max = INT_MAX; ecode++; goto REPEATNOTCHAR; case OP_NOTPOSPLUS: case OP_NOTPOSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; ecode++; goto REPEATNOTCHAR; case OP_NOTPOSQUERY: case OP_NOTPOSQUERYI: possessive = TRUE; min = 0; max = 1; ecode++; goto REPEATNOTCHAR; case OP_NOTPOSUPTO: case OP_NOTPOSUPTOI: possessive = TRUE; min = 0; max = GET2(ecode, 1); ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTSTAR: case OP_NOTSTARI: case OP_NOTMINSTAR: case OP_NOTMINSTARI: case OP_NOTPLUS: case OP_NOTPLUSI: case OP_NOTMINPLUS: case OP_NOTMINPLUSI: case OP_NOTQUERY: case OP_NOTQUERYI: case OP_NOTMINQUERY: case OP_NOTMINQUERYI: c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR); minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single-byte matches. */ REPEATNOTCHAR: GETCHARINCTEST(fc, ecode); /* The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if minimizing, keep trying the rest of the expression and advancing one matching character if failing, up to the maximum. Alternatively, if maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, (char *)eptr)); if (op >= OP_NOTSTARI) /* Caseless */ { #ifdef SUPPORT_UTF #ifdef SUPPORT_UCP if (utf && fc > 127) foc = UCD_OTHERCASE(fc); #else if (utf && fc > 127) foc = fc; #endif /* SUPPORT_UCP */ else #endif /* SUPPORT_UTF */ foc = TABLE_GET(fc, md->fcc, fc); #ifdef SUPPORT_UTF if (utf) { register unsigned int d; for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); eptr++; } } if (min == max) continue; if (minimize) { #ifdef SUPPORT_UTF if (utf) { register unsigned int d; for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM28); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM29); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); eptr++; } } /* Control never gets here */ } /* Maximize case */ else { pp = eptr; #ifdef SUPPORT_UTF if (utf) { register unsigned int d; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(d, eptr, len); if (fc == d || (unsigned int)foc == d) break; eptr += len; } if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM30); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (fc == *eptr || foc == *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM31); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* Caseful comparisons */ else { #ifdef SUPPORT_UTF if (utf) { register unsigned int d; for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } } if (min == max) continue; if (minimize) { #ifdef SUPPORT_UTF if (utf) { register unsigned int d; for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM32); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM33); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* Maximize case */ else { pp = eptr; #ifdef SUPPORT_UTF if (utf) { register unsigned int d; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(d, eptr, len); if (fc == d) break; eptr += len; } if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM34); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (fc == *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM35); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a single character type repeatedly; several different opcodes share code. This is very similar to the code for single characters, but we repeat it in the interests of efficiency. */ case OP_TYPEEXACT: min = max = GET2(ecode, 1); minimize = TRUE; ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPEUPTO: case OP_TYPEMINUPTO: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_TYPEMINUPTO; ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPEPOSSTAR: possessive = TRUE; min = 0; max = INT_MAX; ecode++; goto REPEATTYPE; case OP_TYPEPOSPLUS: possessive = TRUE; min = 1; max = INT_MAX; ecode++; goto REPEATTYPE; case OP_TYPEPOSQUERY: possessive = TRUE; min = 0; max = 1; ecode++; goto REPEATTYPE; case OP_TYPEPOSUPTO: possessive = TRUE; min = 0; max = GET2(ecode, 1); ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: c = *ecode++ - OP_TYPESTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single character type matches. Note that in UTF-8 mode, '.' matches a character of any length, but for the other character types, the valid characters are all one-byte long. */ REPEATTYPE: ctype = *ecode++; /* Code for the character type */ #ifdef SUPPORT_UCP if (ctype == OP_PROP || ctype == OP_NOTPROP) { prop_fail_result = ctype == OP_NOTPROP; prop_type = *ecode++; prop_value = *ecode++; } else prop_type = -1; #endif /* First, ensure the minimum number of matches are present. Use inline code for maximizing the speed, and do the type test once at the start (i.e. keep it out of the loop). Separate the UTF-8 code completely as that is tidier. Also separate the UCP code, which can be the same for both UTF-8 and single-bytes. */ if (min > 0) { #ifdef SUPPORT_UCP if (prop_type >= 0) { switch(prop_type) { case PT_ANY: if (prop_fail_result) RRETURN(MATCH_NOMATCH); for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); } break; case PT_LAMP: for (i = 1; i <= min; i++) { int chartype; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); chartype = UCD_CHARTYPE(c); if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_GC: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_PC: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_SC: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_ALNUM: for (i = 1; i <= min; i++) { int category; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); category = UCD_CATEGORY(c); if ((category == ucp_L || category == ucp_N) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_SPACE: /* Perl space */ for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_PXSPACE: /* POSIX space */ for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_WORD: for (i = 1; i <= min; i++) { int category; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); category = UCD_CATEGORY(c); if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; /* This should not occur */ default: RRETURN(PCRE_ERROR_INTERNAL); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } CHECK_PARTIAL(); } } else #endif /* SUPPORT_UCP */ /* Handle all other cases when the coding is UTF-8 */ #ifdef SUPPORT_UTF if (utf) switch(ctype) { case OP_ANY: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); if (md->partial != 0 && eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; case OP_ALLANY: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; case OP_ANYBYTE: if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH); eptr += min; break; case OP_ANYNL: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: break; case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } break; case OP_NOT_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ RRETURN(MATCH_NOMATCH); } } break; case OP_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; } } break; case OP_NOT_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ RRETURN(MATCH_NOMATCH); } } break; case OP_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ break; } } break; case OP_NOT_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); } break; case OP_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; case OP_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; case OP_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* End switch(ctype) */ else #endif /* SUPPORT_UTF */ /* Code for the non-UTF-8 case for minimum matching of operators other than OP_PROP and OP_NOTPROP. */ switch(ctype) { case OP_ANY: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); if (md->partial != 0 && eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } eptr++; } break; case OP_ALLANY: if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr += min; break; case OP_ANYBYTE: if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } eptr += min; break; case OP_ANYNL: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: break; case 0x000b: case 0x000c: case 0x0085: #ifdef COMPILE_PCRE16 case 0x2028: case 0x2029: #endif if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } break; case OP_NOT_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } switch(*eptr++) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ #ifdef COMPILE_PCRE16 case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ #endif RRETURN(MATCH_NOMATCH); } } break; case OP_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ #ifdef COMPILE_PCRE16 case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ #endif break; } } break; case OP_NOT_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } switch(*eptr++) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ #ifdef COMPILE_PCRE16 case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ #endif RRETURN(MATCH_NOMATCH); } } break; case OP_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ #ifdef COMPILE_PCRE16 case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ #endif break; } } break; case OP_NOT_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); eptr++; } break; case OP_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); eptr++; } break; case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); eptr++; } break; case OP_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); eptr++; } break; case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); eptr++; } break; case OP_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); eptr++; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } } /* If min = max, continue at the same level without recursing */ if (min == max) continue; /* If minimizing, we have to test the rest of the pattern before each subsequent match. Again, separate the UTF-8 case for speed, and also separate the UCP cases. */ if (minimize) { #ifdef SUPPORT_UCP if (prop_type >= 0) { switch(prop_type) { case PT_ANY: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM36); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if (prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_LAMP: for (fi = min;; fi++) { int chartype; RMATCH(eptr, ecode, offset_top, md, eptrb, RM37); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); chartype = UCD_CHARTYPE(c); if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_GC: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM38); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_PC: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM39); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_SC: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM40); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_ALNUM: for (fi = min;; fi++) { int category; RMATCH(eptr, ecode, offset_top, md, eptrb, RM59); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); category = UCD_CATEGORY(c); if ((category == ucp_L || category == ucp_N) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_SPACE: /* Perl space */ for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM60); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_PXSPACE: /* POSIX space */ for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM61); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_WORD: for (fi = min;; fi++) { int category; RMATCH(eptr, ecode, offset_top, md, eptrb, RM62); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); category = UCD_CATEGORY(c); if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ /* This should never occur */ default: RRETURN(PCRE_ERROR_INTERNAL); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM41); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } CHECK_PARTIAL(); } } else #endif /* SUPPORT_UCP */ #ifdef SUPPORT_UTF if (utf) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM42); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (ctype == OP_ANY && IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(ctype) { case OP_ANY: /* This is the non-NL case */ if (md->partial != 0 && /* Take care with CRLF partial */ eptr >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } break; case OP_ALLANY: case OP_ANYBYTE: break; case OP_ANYNL: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: break; case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; case OP_NOT_HSPACE: switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; } break; case OP_NOT_VSPACE: switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ break; } break; case OP_NOT_DIGIT: if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if (c < 256 && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if (c < 256 && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } } else #endif /* Not UTF mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM43); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } if (ctype == OP_ANY && IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); c = *eptr++; switch(ctype) { case OP_ANY: /* This is the non-NL case */ if (md->partial != 0 && /* Take care with CRLF partial */ eptr >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && c == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } break; case OP_ALLANY: case OP_ANYBYTE: break; case OP_ANYNL: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: break; case 0x000b: case 0x000c: case 0x0085: #ifdef COMPILE_PCRE16 case 0x2028: case 0x2029: #endif if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; case OP_NOT_HSPACE: switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ #ifdef COMPILE_PCRE16 case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ #endif RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ #ifdef COMPILE_PCRE16 case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ #endif break; } break; case OP_NOT_VSPACE: switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ #ifdef COMPILE_PCRE16 case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ #endif RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ #ifdef COMPILE_PCRE16 case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ #endif break; } break; case OP_NOT_DIGIT: if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } } /* Control never gets here */ } /* If maximizing, it is worth using inline code for speed, doing the type test once at the start (i.e. keep it out of the loop). Again, keep the UTF-8 and UCP stuff separate. */ else { pp = eptr; /* Remember where we started */ #ifdef SUPPORT_UCP if (prop_type >= 0) { switch(prop_type) { case PT_ANY: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); if (prop_fail_result) break; eptr+= len; } break; case PT_LAMP: for (i = min; i < max; i++) { int chartype; int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); chartype = UCD_CHARTYPE(c); if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) == prop_fail_result) break; eptr+= len; } break; case PT_GC: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; case PT_PC: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; case PT_SC: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; case PT_ALNUM: for (i = min; i < max; i++) { int category; int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); category = UCD_CATEGORY(c); if ((category == ucp_L || category == ucp_N) == prop_fail_result) break; eptr+= len; } break; case PT_SPACE: /* Perl space */ for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) break; eptr+= len; } break; case PT_PXSPACE: /* POSIX space */ for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) break; eptr+= len; } break; case PT_WORD: for (i = min; i < max; i++) { int category; int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLENTEST(c, eptr, len); category = UCD_CATEGORY(c); if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) break; eptr+= len; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run */ if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM44); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ if (utf) BACKCHAR(eptr); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } if (UCD_CATEGORY(c) == ucp_M) break; eptr += len; while (eptr < md->end_subject) { len = 1; if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } CHECK_PARTIAL(); } /* eptr is now past the end of the maximum run */ if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM45); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ for (;;) /* Move back over one extended */ { if (!utf) c = *eptr; else { BACKCHAR(eptr); GETCHAR(c, eptr); } if (UCD_CATEGORY(c) != ucp_M) break; eptr--; } } } else #endif /* SUPPORT_UCP */ #ifdef SUPPORT_UTF if (utf) { switch(ctype) { case OP_ANY: if (max < INT_MAX) { for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (IS_NEWLINE(eptr)) break; if (md->partial != 0 && /* Take care with CRLF partial */ eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } /* Handle unlimited UTF-8 repeat */ else { for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (IS_NEWLINE(eptr)) break; if (md->partial != 0 && /* Take care with CRLF partial */ eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } break; case OP_ALLANY: if (max < INT_MAX) { for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } else { eptr = md->end_subject; /* Unlimited UTF-8 repeat */ SCHECK_PARTIAL(); } break; /* The byte case is the same as non-UTF8 */ case OP_ANYBYTE: c = max - min; if (c > (unsigned int)(md->end_subject - eptr)) { eptr = md->end_subject; SCHECK_PARTIAL(); } else eptr += c; break; case OP_ANYNL: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c == 0x000d) { if (++eptr >= md->end_subject) break; if (*eptr == 0x000a) eptr++; } else { if (c != 0x000a && (md->bsr_anycrlf || (c != 0x000b && c != 0x000c && c != 0x0085 && c != 0x2028 && c != 0x2029))) break; eptr += len; } } break; case OP_NOT_HSPACE: case OP_HSPACE: for (i = min; i < max; i++) { BOOL gotspace; int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); switch(c) { default: gotspace = FALSE; break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ gotspace = TRUE; break; } if (gotspace == (ctype == OP_NOT_HSPACE)) break; eptr += len; } break; case OP_NOT_VSPACE: case OP_VSPACE: for (i = min; i < max; i++) { BOOL gotspace; int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); switch(c) { default: gotspace = FALSE; break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ gotspace = TRUE; break; } if (gotspace == (ctype == OP_NOT_VSPACE)) break; eptr += len; } break; case OP_NOT_DIGIT: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break; eptr+= len; } break; case OP_DIGIT: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break; eptr+= len; } break; case OP_NOT_WHITESPACE: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break; eptr+= len; } break; case OP_WHITESPACE: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break; eptr+= len; } break; case OP_NOT_WORDCHAR: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break; eptr+= len; } break; case OP_WORDCHAR: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } GETCHARLEN(c, eptr, len); if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break; eptr+= len; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run. If possessive, we are done (no backing up). Otherwise, match at this position; anything other than no match is immediately returned. For nomatch, back up one character, unless we are matching \R and the last thing matched was \r\n, in which case, back up two bytes. */ if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM46); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && eptr[-1] == '\r') eptr--; } } else #endif /* SUPPORT_UTF */ /* Not UTF mode */ { switch(ctype) { case OP_ANY: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (IS_NEWLINE(eptr)) break; if (md->partial != 0 && /* Take care with CRLF partial */ eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } eptr++; } break; case OP_ALLANY: case OP_ANYBYTE: c = max - min; if (c > (unsigned int)(md->end_subject - eptr)) { eptr = md->end_subject; SCHECK_PARTIAL(); } else eptr += c; break; case OP_ANYNL: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } c = *eptr; if (c == 0x000d) { if (++eptr >= md->end_subject) break; if (*eptr == 0x000a) eptr++; } else { if (c != 0x000a && (md->bsr_anycrlf || (c != 0x000b && c != 0x000c && c != 0x0085 #ifdef COMPILE_PCRE16 && c != 0x2028 && c != 0x2029 #endif ))) break; eptr++; } } break; case OP_NOT_HSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } c = *eptr; if (c == 0x09 || c == 0x20 || c == 0xa0 #ifdef COMPILE_PCRE16 || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A) || c == 0x202f || c == 0x205f || c == 0x3000 #endif ) break; eptr++; } break; case OP_HSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } c = *eptr; if (c != 0x09 && c != 0x20 && c != 0xa0 #ifdef COMPILE_PCRE16 && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A) && c != 0x202f && c != 0x205f && c != 0x3000 #endif ) break; eptr++; } break; case OP_NOT_VSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } c = *eptr; if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85 #ifdef COMPILE_PCRE16 || c == 0x2028 || c == 0x2029 #endif ) break; eptr++; } break; case OP_VSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } c = *eptr; if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85 #ifdef COMPILE_PCRE16 && c != 0x2028 && c != 0x2029 #endif ) break; eptr++; } break; case OP_NOT_DIGIT: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break; eptr++; } break; case OP_DIGIT: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break; eptr++; } break; case OP_NOT_WHITESPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break; eptr++; } break; case OP_WHITESPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break; eptr++; } break; case OP_NOT_WORDCHAR: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break; eptr++; } break; case OP_WORDCHAR: for (i = min; i < max; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break; eptr++; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run. If possessive, we are done (no backing up). Otherwise, match at this position; anything other than no match is immediately returned. For nomatch, back up one character (byte), unless we are matching \R and the last thing matched was \r\n, in which case, back up two bytes. */ if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM47); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && eptr[-1] == '\r') eptr--; } } /* Get here if we can't make it match with any permitted repetitions */ RRETURN(MATCH_NOMATCH); } /* Control never gets here */ /* There's been some horrible disaster. Arrival here can only mean there is something seriously wrong in the code above or the OP_xxx definitions. */ default: DPRINTF(("Unknown opcode %d\n", *ecode)); RRETURN(PCRE_ERROR_UNKNOWN_OPCODE); } /* Do not stick any code in here without much thought; it is assumed that "continue" in the code above comes out to here to repeat the main loop. */ } /* End of main loop */ /* Control never reaches here */ /* When compiling to use the heap rather than the stack for recursive calls to match(), the RRETURN() macro jumps here. The number that is saved in frame->Xwhere indicates which label we actually want to return to. */ #ifdef NO_RECURSE #define LBL(val) case val: goto L_RM##val; HEAP_RETURN: switch (frame->Xwhere) { LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17) LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33) LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) LBL(65) LBL(66) #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 LBL(21) #endif #ifdef SUPPORT_UTF LBL(16) LBL(18) LBL(20) LBL(22) LBL(23) LBL(28) LBL(30) LBL(32) LBL(34) LBL(42) LBL(46) #ifdef SUPPORT_UCP LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) LBL(59) LBL(60) LBL(61) LBL(62) #endif /* SUPPORT_UCP */ #endif /* SUPPORT_UTF */ default: DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere); return PCRE_ERROR_INTERNAL; } #undef LBL #endif /* NO_RECURSE */ } /*************************************************************************** **************************************************************************** RECURSION IN THE match() FUNCTION Undefine all the macros that were defined above to handle this. */ #ifdef NO_RECURSE #undef eptr #undef ecode #undef mstart #undef offset_top #undef eptrb #undef flags #undef callpat #undef charptr #undef data #undef next #undef pp #undef prev #undef saved_eptr #undef new_recursive #undef cur_is_word #undef condition #undef prev_is_word #undef ctype #undef length #undef max #undef min #undef number #undef offset #undef op #undef save_capture_last #undef save_offset1 #undef save_offset2 #undef save_offset3 #undef stacksave #undef newptrb #endif /* These two are defined as macros in both cases */ #undef fc #undef fi /*************************************************************************** ***************************************************************************/ #ifdef NO_RECURSE /************************************************* * Release allocated heap frames * *************************************************/ /* This function releases all the allocated frames. The base frame is on the machine stack, and so must not be freed. Argument: the address of the base frame Returns: nothing */ static void release_match_heapframes (heapframe *frame_base) { heapframe *nextframe = frame_base->Xnextframe; while (nextframe != NULL) { heapframe *oldframe = nextframe; nextframe = nextframe->Xnextframe; (PUBL(stack_free))(oldframe); } } #endif /************************************************* * Execute a Regular Expression * *************************************************/ /* This function applies a compiled re to a subject string and picks out portions of the string if it matches. Two elements in the vector are set for each substring: the offsets to the start and end of the substring. Arguments: argument_re points to the compiled expression extra_data points to extra data or is NULL subject points to the subject string length length of subject string (may contain binary zeros) start_offset where to start in the subject string options option bits offsets points to a vector of ints to be filled in with offsets offsetcount the number of elements in the vector Returns: > 0 => success; value is the number of elements filled in = 0 => success, but offsets is not big enough -1 => failed to match < -1 => some kind of unexpected problem */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, int offsetcount) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, int offsetcount) #endif { int rc, ocount, arg_offset_max; int newline; BOOL using_temporary_offsets = FALSE; BOOL anchored; BOOL startline; BOOL firstline; BOOL utf; BOOL has_first_char = FALSE; BOOL has_req_char = FALSE; pcre_uchar first_char = 0; pcre_uchar first_char2 = 0; pcre_uchar req_char = 0; pcre_uchar req_char2 = 0; match_data match_block; match_data *md = &match_block; const pcre_uint8 *tables; const pcre_uint8 *start_bits = NULL; PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset; PCRE_PUCHAR end_subject; PCRE_PUCHAR start_partial = NULL; PCRE_PUCHAR req_char_ptr = start_match - 1; const pcre_study_data *study; const REAL_PCRE *re = (const REAL_PCRE *)argument_re; #ifdef NO_RECURSE heapframe frame_zero; frame_zero.Xprevframe = NULL; /* Marks the top level */ frame_zero.Xnextframe = NULL; /* None are allocated yet */ md->match_frames_base = &frame_zero; #endif /* Check for the special magic call that measures the size of the stack used per recursive call of match(). Without the funny casting for sizeof, a Windows compiler gave this error: "unary minus operator applied to unsigned type, result still unsigned". Hopefully the cast fixes that. */ if (re == NULL && extra_data == NULL && subject == NULL && length == -999 && start_offset == -999) #ifdef NO_RECURSE return -((int)sizeof(heapframe)); #else return match(NULL, NULL, NULL, 0, NULL, NULL, 0); #endif /* Plausibility checks */ if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; /* Check that the first field in the block is the magic number. If it is not, return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which means that the pattern is likely compiled with different endianness. */ if (re->magic_number != MAGIC_NUMBER) return re->magic_number == REVERSED_MAGIC_NUMBER? PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; /* These two settings are used in the code for checking a UTF-8 string that follows immediately afterwards. Other values in the md block are used only during "normal" pcre_exec() processing, not when the JIT support is in use, so they are set up later. */ /* PCRE_UTF16 has the same value as PCRE_UTF8. */ utf = md->utf = (re->options & PCRE_UTF8) != 0; md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 : ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0; /* Check a UTF-8 string if required. Pass back the character offset and error code for an invalid string if a results vector is available. */ #ifdef SUPPORT_UTF if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) { int erroroffset; int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset); if (errorcode != 0) { if (offsetcount >= 2) { offsets[0] = erroroffset; offsets[1] = errorcode; } #ifdef COMPILE_PCRE16 return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)? PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; #else return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; #endif } /* Check that a start_offset points to the start of a UTF character. */ if (start_offset > 0 && start_offset < length && NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) return PCRE_ERROR_BADUTF8_OFFSET; } #endif /* If the pattern was successfully studied with JIT support, run the JIT executable instead of the rest of this function. Most options must be set at compile time for the JIT code to be usable. Fallback to the normal code path if an unsupported flag is set. */ #ifdef SUPPORT_JIT if (extra_data != NULL && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT | PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT && extra_data->executable_jit != NULL && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0) { rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length, start_offset, options, offsets, offsetcount); /* PCRE_ERROR_NULL means that the selected normal or partial matching mode is not compiled. In this case we simply fallback to interpreter. */ if (rc != PCRE_ERROR_NULL) return rc; } #endif /* Carry on with non-JIT matching. This information is for finding all the numbers associated with a given name, for condition testing. */ md->name_table = (pcre_uchar *)re + re->name_table_offset; md->name_count = re->name_count; md->name_entry_size = re->name_entry_size; /* Fish out the optional data from the extra_data structure, first setting the default values. */ study = 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. */ tables = re->tables; if (extra_data != NULL) { register unsigned int flags = extra_data->flags; if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) md->match_limit = extra_data->match_limit; if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0) md->match_limit_recursion = extra_data->match_limit_recursion; if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) md->callout_data = extra_data->callout_data; if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables; } /* If the exec call supplied NULL for tables, use the inbuilt ones. This is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ if (tables == NULL) tables = PRIV(default_tables); /* Set up other data */ anchored = ((re->options | options) & PCRE_ANCHORED) != 0; startline = (re->flags & PCRE_STARTLINE) != 0; firstline = (re->options & PCRE_FIRSTLINE) != 0; /* The code starts after the real_pcre block and the capture name table. */ md->start_code = (const pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; md->start_subject = (PCRE_PUCHAR)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->use_ucp = (re->options & PCRE_UCP) != 0; md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; md->ignore_skip_arg = FALSE; /* Some options are unpacked into BOOL variables in the hope that testing them will be faster than individual option bits. */ md->notbol = (options & PCRE_NOTBOL) != 0; md->noteol = (options & PCRE_NOTEOL) != 0; md->notempty = (options & PCRE_NOTEMPTY) != 0; md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; md->hitend = FALSE; md->mark = md->nomatch_mark = NULL; /* In case never set */ md->recursive = NULL; /* No recursion at top level */ md->hasthen = (re->flags & PCRE_HASTHEN) != 0; md->lcc = tables + lcc_offset; md->fcc = tables + fcc_offset; md->ctypes = tables + ctypes_offset; /* Handle different \R options. */ switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) { case 0: if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0) md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0; else #ifdef BSR_ANYCRLF md->bsr_anycrlf = TRUE; #else md->bsr_anycrlf = FALSE; #endif break; case PCRE_BSR_ANYCRLF: md->bsr_anycrlf = TRUE; break; case PCRE_BSR_UNICODE: md->bsr_anycrlf = FALSE; break; default: return PCRE_ERROR_BADNEWLINE; } /* Handle different types of newline. The three bits give eight cases. If nothing is set at run time, whatever was used at compile time applies. */ switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) & PCRE_NEWLINE_BITS) { case 0: newline = NEWLINE; break; /* Compile-time default */ case PCRE_NEWLINE_CR: newline = CHAR_CR; break; case PCRE_NEWLINE_LF: newline = CHAR_NL; break; case PCRE_NEWLINE_CR+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break; case PCRE_NEWLINE_ANY: newline = -1; break; case PCRE_NEWLINE_ANYCRLF: newline = -2; break; default: return PCRE_ERROR_BADNEWLINE; } if (newline == -2) { md->nltype = NLTYPE_ANYCRLF; } else if (newline < 0) { md->nltype = NLTYPE_ANY; } else { md->nltype = NLTYPE_FIXED; 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 was originally supported only for a restricted set of regexes; from release 8.00 there are no restrictions, but the bits are still defined (though never set). So there's no harm in leaving this code. */ if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0) return PCRE_ERROR_BADPARTIAL; /* If the expression has got more back references than the offsets supplied can hold, we get a temporary chunk of working store to use during the matching. Otherwise, we can use the vector supplied, rounding down its size to a multiple of 3. */ ocount = offsetcount - (offsetcount % 3); arg_offset_max = (2*ocount)/3; if (re->top_backref > 0 && re->top_backref >= ocount/3) { ocount = re->top_backref * 3 + 3; md->offset_vector = (int *)(PUBL(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 md->offset_vector = offsets; md->offset_end = ocount; md->offset_max = (2*ocount)/3; md->offset_overflow = FALSE; md->capture_last = -1; /* Reset the working variable associated with each extraction. These should never be used unless previously set, but they get saved and restored, and so we initialize them to avoid reading uninitialized locations. Also, unset the offsets for the matched string. This is really just for tidiness with callouts, in case they inspect these fields. */ if (md->offset_vector != NULL) { register int *iptr = md->offset_vector + ocount; register int *iend = iptr - re->top_bracket; if (iend < md->offset_vector + 2) iend = md->offset_vector + 2; while (--iptr >= iend) *iptr = -1; md->offset_vector[0] = md->offset_vector[1] = -1; } /* Set up the first character to match, if available. The first_char value is never set for an anchored regular expression, but the anchoring may be forced at run time, so we have to test for anchoring. The first char may be unset for an unanchored pattern, of course. If there's no first char and the pattern was studied, there may be a bitmap of possible first characters. */ if (!anchored) { if ((re->flags & PCRE_FIRSTSET) != 0) { has_first_char = TRUE; first_char = first_char2 = (pcre_uchar)(re->first_char); if ((re->flags & PCRE_FCH_CASELESS) != 0) { first_char2 = TABLE_GET(first_char, md->fcc, first_char); #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) if (utf && first_char > 127) first_char2 = UCD_OTHERCASE(first_char); #endif } } else if (!startline && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) start_bits = study->start_bits; } /* For anchored or unanchored matches, there may be a "last known required character" set. */ if ((re->flags & PCRE_REQCHSET) != 0) { has_req_char = TRUE; req_char = req_char2 = (pcre_uchar)(re->req_char); if ((re->flags & PCRE_RCH_CASELESS) != 0) { req_char2 = TABLE_GET(req_char, md->fcc, req_char); #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) if (utf && req_char > 127) req_char2 = UCD_OTHERCASE(req_char); #endif } } /* ==========================================================================*/ /* Loop for handling unanchored repeated matching attempts; for anchored regexs the loop runs just once. */ for(;;) { PCRE_PUCHAR save_end_subject = end_subject; PCRE_PUCHAR new_start_match; /* If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. That is, the match must be before or at the first newline. Implement this by temporarily adjusting end_subject so that we stop scanning at a newline. If the match fails at the newline, later code breaks this loop. */ if (firstline) { PCRE_PUCHAR t = start_match; #ifdef SUPPORT_UTF if (utf) { while (t < md->end_subject && !IS_NEWLINE(t)) { t++; ACROSSCHAR(t < end_subject, *t, t++); } } else #endif while (t < md->end_subject && !IS_NEWLINE(t)) t++; end_subject = t; } /* There are some optimizations that avoid running the match if a known starting point is not found, or if a known later character is not present. However, there is an option that disables these, for testing and for ensuring that all callouts do actually occur. The option can be set in the regex by (*NO_START_OPT) or passed in match-time options. */ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) { /* Advance to a unique first char if there is one. */ if (has_first_char) { if (first_char != first_char2) while (start_match < end_subject && *start_match != first_char && *start_match != first_char2) start_match++; else while (start_match < end_subject && *start_match != first_char) start_match++; } /* Or to just after a linebreak for a multiline match */ else if (startline) { if (start_match > md->start_subject + start_offset) { #ifdef SUPPORT_UTF if (utf) { while (start_match < end_subject && !WAS_NEWLINE(start_match)) { start_match++; ACROSSCHAR(start_match < end_subject, *start_match, start_match++); } } else #endif while (start_match < end_subject && !WAS_NEWLINE(start_match)) start_match++; /* If we have just passed a CR and the newline option is ANY or ANYCRLF, and we are now at a LF, advance the match position by one more character. */ if (start_match[-1] == CHAR_CR && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && start_match < end_subject && *start_match == CHAR_NL) start_match++; } } /* Or to a non-unique first byte after study */ else if (start_bits != NULL) { while (start_match < end_subject) { register unsigned int c = *start_match; #ifndef COMPILE_PCRE8 if (c > 255) c = 255; #endif if ((start_bits[c/8] & (1 << (c&7))) == 0) { start_match++; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 /* In non 8-bit mode, the iteration will stop for characters > 255 at the beginning or not stop at all. */ if (utf) ACROSSCHAR(start_match < end_subject, *start_match, start_match++); #endif } else break; } } } /* Starting optimizations */ /* Restore fudged end_subject */ end_subject = save_end_subject; /* The following two optimizations are disabled for partial matching or if disabling is explicitly requested. */ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial) { /* If the pattern was studied, a minimum subject length may be set. This is a lower bound; no actual string of that length may actually match the pattern. Although the value is, strictly, in characters, we treat it as bytes to avoid spending too much time in this optimization. */ if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 && (pcre_uint32)(end_subject - start_match) < study->minlength) { rc = MATCH_NOMATCH; break; } /* If req_char is set, we know that that character must appear in the subject for the match to succeed. If the first character is set, req_char must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of backtracking in patterns with nested unlimited repeats that aren't going to match. Writing separate code for cased/caseless versions makes it go faster, as does using an autoincrement and backing off on a match. HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary patterns. This showed up when somebody was matching something like /^\d+C/ on a 32-megabyte string... so we don't do this when the string is sufficiently long. */ if (has_req_char && end_subject - start_match < REQ_BYTE_MAX) { register PCRE_PUCHAR p = start_match + (has_first_char? 1:0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ if (p > req_char_ptr) { if (req_char != req_char2) { while (p < end_subject) { register int pp = *p++; if (pp == req_char || pp == req_char2) { p--; break; } } } else { while (p < end_subject) { if (*p++ == req_char) { p--; break; } } } /* If we can't find the required character, break the matching loop, forcing a match failure. */ if (p >= end_subject) { rc = MATCH_NOMATCH; break; } /* If we have found the required character, save the point where we found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ req_char_ptr = p; } } } #ifdef PCRE_DEBUG /* Sigh. Some compilers never learn. */ printf(">>>> Match against: "); pchars(start_match, end_subject - start_match, TRUE, md); printf("\n"); #endif /* OK, we can now run the match. If "hitend" is set afterwards, remember the first starting point for which a partial match was found. */ md->start_match_ptr = start_match; md->start_used_ptr = start_match; md->match_call_count = 0; md->match_function_type = 0; md->end_offset_top = 0; rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0); if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr; switch(rc) { /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP entirely. The only way we can do that is to re-do the match at the same point, with a flag to force SKIP with an argument to be ignored. Just treating this case as NOMATCH does not work because it does not check other alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */ case MATCH_SKIP_ARG: new_start_match = start_match; md->ignore_skip_arg = TRUE; break; /* SKIP passes back the next starting point explicitly, but if it is the same as the match we have just done, treat it as NOMATCH. */ case MATCH_SKIP: if (md->start_match_ptr != start_match) { new_start_match = md->start_match_ptr; break; } /* Fall through */ /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */ case MATCH_NOMATCH: case MATCH_PRUNE: case MATCH_THEN: md->ignore_skip_arg = FALSE; new_start_match = start_match + 1; #ifdef SUPPORT_UTF if (utf) ACROSSCHAR(new_start_match < end_subject, *new_start_match, new_start_match++); #endif break; /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */ case MATCH_COMMIT: rc = MATCH_NOMATCH; goto ENDLOOP; /* Any other return is either a match, or some kind of error. */ default: goto ENDLOOP; } /* Control reaches here for the various types of "no match at this point" result. Reset the code to MATCH_NOMATCH for subsequent checking. */ rc = MATCH_NOMATCH; /* If PCRE_FIRSTLINE is set, the match must happen before or at the first newline in the subject (though it may continue over the newline). Therefore, if we have just failed to match, starting at a newline, do not continue. */ if (firstline && IS_NEWLINE(start_match)) break; /* Advance to new matching position */ start_match = new_start_match; /* Break the loop if the pattern is anchored or if we have passed the end of the subject. */ if (anchored || start_match > end_subject) break; /* If we have just passed a CR and we are now at a LF, and the pattern does not contain any explicit matches for \r or \n, and the newline option is CRLF or ANY or ANYCRLF, advance the match position by one more character. In normal matching start_match will aways be greater than the first position at this stage, but a failed *SKIP can cause a return at the same point, which is why the first test exists. */ if (start_match > (PCRE_PUCHAR)subject + start_offset && start_match[-1] == CHAR_CR && start_match < end_subject && *start_match == CHAR_NL && (re->flags & PCRE_HASCRORLF) == 0 && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF || md->nllen == 2)) start_match++; md->mark = NULL; /* Reset for start of next match attempt */ } /* End of for(;;) "bumpalong" loop */ /* ==========================================================================*/ /* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping conditions is true: (1) The pattern is anchored or the match was failed by (*COMMIT); (2) We are past the end of the subject; (3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because this option requests that a match occur at or before the first newline in the subject. When we have a match and the offset vector is big enough to deal with any backreferences, captured substring offsets will already be set up. In the case where we had to get some local store to hold offsets for backreference processing, copy those that we can. In this case there need not be overflow if certain parts of the pattern were not used, even though there are more capturing parentheses than vector slots. */ ENDLOOP: if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) { if (using_temporary_offsets) { if (arg_offset_max >= 4) { memcpy(offsets + 2, md->offset_vector + 2, (arg_offset_max - 2) * sizeof(int)); DPRINTF(("Copied offsets from temporary memory\n")); } if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE; DPRINTF(("Freeing temporary memory\n")); (PUBL(free))(md->offset_vector); } /* Set the return code to the number of captured strings, or 0 if there were too many to fit into the vector. */ rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)? 0 : md->end_offset_top/2; /* If there is space in the offset vector, set any unused pairs at the end of the pattern to -1 for backwards compatibility. It is documented that this happens. In earlier versions, the whole set of potential capturing offsets was set to -1 each time round the loop, but this is handled differently now. "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only those at the end that need unsetting here. We can't just unset them all at the start of the whole thing because they may get set in one branch that is not the final matching branch. */ if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL) { register int *iptr, *iend; int resetcount = 2 + re->top_bracket * 2; if (resetcount > offsetcount) resetcount = offsetcount; iptr = offsets + md->end_offset_top; iend = offsets + resetcount; while (iptr < iend) *iptr++ = -1; } /* If there is space, set up the whole thing as substring 0. The value of md->start_match_ptr might be modified if \K was encountered on the success matching path. */ if (offsetcount < 2) rc = 0; else { offsets[0] = (int)(md->start_match_ptr - md->start_subject); offsets[1] = (int)(md->end_match_ptr - md->start_subject); } /* Return MARK data if requested */ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) *(extra_data->mark) = (pcre_uchar *)md->mark; DPRINTF((">>>> returning %d\n", rc)); #ifdef NO_RECURSE release_match_heapframes(&frame_zero); #endif return rc; } /* Control gets here if there has been an error, or if the overall match attempt has failed at all permitted starting positions. */ if (using_temporary_offsets) { DPRINTF(("Freeing temporary memory\n")); (PUBL(free))(md->offset_vector); } /* For anything other than nomatch or partial match, just return the code. */ if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL) { DPRINTF((">>>> error: returning %d\n", rc)); #ifdef NO_RECURSE release_match_heapframes(&frame_zero); #endif return rc; } /* Handle partial matches - disable any mark data */ if (start_partial != NULL) { DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n")); md->mark = NULL; if (offsetcount > 1) { offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject); offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject); } rc = PCRE_ERROR_PARTIAL; } /* This is the classic nomatch case */ else { DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n")); rc = PCRE_ERROR_NOMATCH; } /* Return the MARK data if it has been requested. */ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark; #ifdef NO_RECURSE release_match_heapframes(&frame_zero); #endif return rc; } /* End of pcre_exec.c */ pcre-8.31/config.sub0000755000222100022210000010555411775524614011314 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx | dvp \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mipsEE* | ee | ps2) basic_machine=mips64r5900el-scei case $os in -linux*) ;; *) os=-elf ;; esac ;; iop) basic_machine=mipsel-scei os=-irx ;; dvp) basic_machine=dvp-scei os=-elf ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -irx* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: pcre-8.31/pcre_printint.c0000644000222100022210000004655011721171641012342 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains a PCRE private debugging function for printing out the internal form of a compiled regular expression, along with some supporting local functions. This source file is used in two places: (1) It is #included by pcre_compile.c when it is compiled in debugging mode (PCRE_DEBUG defined in pcre_internal.h). It is not included in production compiles. In this case PCRE_INCLUDED is defined. (2) It is also compiled separately and linked with pcretest.c, which can be asked to print out a compiled regex for debugging purposes. */ #ifndef PCRE_INCLUDED #ifdef HAVE_CONFIG_H #include "config.h" #endif /* For pcretest program. */ #define PRIV(name) name /* We have to include pcre_internal.h because we need the internal info for displaying the results of pcre_study() and we also need to know about the internal macros, structures, and other internal data values; pcretest has "inside information" compared to a program that strictly follows the PCRE API. Although pcre_internal.h does itself include pcre.h, we explicitly include it here before pcre_internal.h so that the PCRE_EXP_xxx macros get set appropriately for an application, not for building PCRE. */ #include "pcre.h" #include "pcre_internal.h" /* These are the funtions that are contained within. It doesn't seem worth having a separate .h file just for this. */ #endif /* PCRE_INCLUDED */ #ifdef PCRE_INCLUDED static /* Keep the following function as private. */ #endif #ifdef COMPILE_PCRE8 void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths); #else void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths); #endif /* Macro that decides whether a character should be output as a literal or in hexadecimal. We don't use isprint() because that can vary from system to system (even without the use of locales) and we want the output always to be the same, for testing purposes. */ #ifdef EBCDIC #define PRINTABLE(c) ((c) >= 64 && (c) < 255) #else #define PRINTABLE(c) ((c) >= 32 && (c) < 127) #endif /* The table of operator names. */ static const char *priv_OP_names[] = { OP_NAME_LIST }; /* This table of operator lengths is not actually used by the working code, but its size is needed for a check that ensures it is the correct size for the number of opcodes (thus catching update omissions). */ static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS }; /************************************************* * Print single- or multi-byte character * *************************************************/ static int print_char(FILE *f, pcre_uchar *ptr, BOOL utf) { int c = *ptr; #ifndef SUPPORT_UTF (void)utf; /* Avoid compiler warning */ if (PRINTABLE(c)) fprintf(f, "%c", c); else if (c <= 0xff) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); return 0; #else #ifdef COMPILE_PCRE8 if (!utf || (c & 0xc0) != 0xc0) { if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); return 0; } else { int i; int a = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */ int s = 6*a; c = (c & PRIV(utf8_table3)[a]) << s; for (i = 1; i <= a; i++) { /* This is a check for malformed UTF-8; it should only occur if the sanity check has been turned off. Rather than swallow random bytes, just stop if we hit a bad one. Print it with \X instead of \x as an indication. */ if ((ptr[i] & 0xc0) != 0x80) { fprintf(f, "\\X{%x}", c); return i - 1; } /* The byte is OK */ s -= 6; c |= (ptr[i] & 0x3f) << s; } fprintf(f, "\\x{%x}", c); return a; } #else #ifdef COMPILE_PCRE16 if (!utf || (c & 0xfc00) != 0xd800) { if (PRINTABLE(c)) fprintf(f, "%c", c); else if (c <= 0xff) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); return 0; } else { /* This is a check for malformed UTF-16; it should only occur if the sanity check has been turned off. Rather than swallow a low surrogate, just stop if we hit a bad one. Print it with \X instead of \x as an indication. */ if ((ptr[1] & 0xfc00) != 0xdc00) { fprintf(f, "\\X{%x}", c); return 0; } c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000; fprintf(f, "\\x{%x}", c); return 1; } #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ #endif /* SUPPORT_UTF */ } /************************************************* * Print uchar string (regardless of utf) * *************************************************/ static void print_puchar(FILE *f, PCRE_PUCHAR ptr) { while (*ptr != '\0') { register int c = *ptr++; if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); } } /************************************************* * Find Unicode property name * *************************************************/ static const char * get_ucpname(int ptype, int pvalue) { #ifdef SUPPORT_UCP int i; for (i = PRIV(utt_size) - 1; i >= 0; i--) { if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break; } return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??"; #else /* It gets harder and harder to shut off unwanted compiler warnings. */ ptype = ptype * pvalue; return (ptype == pvalue)? "??" : "??"; #endif } /************************************************* * Print compiled regex * *************************************************/ /* Make this function work for a regex with integers either byte order. However, we assume that what we are passed is a compiled regex. The print_lengths flag controls whether offsets and lengths of items are printed. They can be turned off from pcretest so that automatic tests on bytecode can be written that do not depend on the value of LINK_SIZE. */ #ifdef PCRE_INCLUDED static /* Keep the following function as private. */ #endif #ifdef COMPILE_PCRE8 void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths) #else void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths) #endif { REAL_PCRE *re = (REAL_PCRE *)external_re; pcre_uchar *codestart, *code; BOOL utf; unsigned int options = re->options; int offset = re->name_table_offset; int count = re->name_count; int size = re->name_entry_size; if (re->magic_number != MAGIC_NUMBER) { offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff); count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff); size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff); options = ((options << 24) & 0xff000000) | ((options << 8) & 0x00ff0000) | ((options >> 8) & 0x0000ff00) | ((options >> 24) & 0x000000ff); } code = codestart = (pcre_uchar *)re + offset + count * size; /* PCRE_UTF16 has the same value as PCRE_UTF8. */ utf = (options & PCRE_UTF8) != 0; for(;;) { pcre_uchar *ccode; const char *flag = " "; int c; int extra = 0; if (print_lengths) fprintf(f, "%3d ", (int)(code - codestart)); else fprintf(f, " "); switch(*code) { /* ========================================================================== */ /* These cases are never obeyed. This is a fudge that causes a compile- time error if the vectors OP_names or OP_lengths, which are indexed by opcode, are not the correct length. It seems to be the only way to do such a check at compile time, as the sizeof() operator does not work in the C preprocessor. */ case OP_TABLE_LENGTH: case OP_TABLE_LENGTH + ((sizeof(priv_OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) && (sizeof(priv_OP_lengths) == OP_TABLE_LENGTH)): break; /* ========================================================================== */ case OP_END: fprintf(f, " %s\n", priv_OP_names[*code]); fprintf(f, "------------------------------------------------------------------\n"); return; case OP_CHAR: fprintf(f, " "); do { code++; code += 1 + print_char(f, code, utf); } while (*code == OP_CHAR); fprintf(f, "\n"); continue; case OP_CHARI: fprintf(f, " /i "); do { code++; code += 1 + print_char(f, code, utf); } while (*code == OP_CHARI); fprintf(f, "\n"); continue; case OP_CBRA: case OP_CBRAPOS: case OP_SCBRA: case OP_SCBRAPOS: if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); else fprintf(f, " "); fprintf(f, "%s %d", priv_OP_names[*code], GET2(code, 1+LINK_SIZE)); break; case OP_BRA: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: case OP_KETRMAX: case OP_KETRMIN: case OP_KETRPOS: case OP_ALT: case OP_KET: case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: case OP_ONCE_NC: case OP_COND: case OP_SCOND: case OP_REVERSE: if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); else fprintf(f, " "); fprintf(f, "%s", priv_OP_names[*code]); break; case OP_CLOSE: fprintf(f, " %s %d", priv_OP_names[*code], GET2(code, 1)); break; case OP_CREF: case OP_NCREF: fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]); break; case OP_RREF: c = GET2(code, 1); if (c == RREF_ANY) fprintf(f, " Cond recurse any"); else fprintf(f, " Cond recurse %d", c); break; case OP_NRREF: c = GET2(code, 1); if (c == RREF_ANY) fprintf(f, " Cond nrecurse any"); else fprintf(f, " Cond nrecurse %d", c); break; case OP_DEF: fprintf(f, " Cond def"); break; case OP_STARI: case OP_MINSTARI: case OP_POSSTARI: case OP_PLUSI: case OP_MINPLUSI: case OP_POSPLUSI: case OP_QUERYI: case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: fprintf(f, " %s ", flag); if (*code >= OP_TYPESTAR) { fprintf(f, "%s", priv_OP_names[code[1]]); if (code[1] == OP_PROP || code[1] == OP_NOTPROP) { fprintf(f, " %s ", get_ucpname(code[2], code[3])); extra = 2; } } else extra = print_char(f, code+1, utf); fprintf(f, "%s", priv_OP_names[*code]); break; case OP_EXACTI: case OP_UPTOI: case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; /* Fall through */ case OP_EXACT: case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: fprintf(f, " %s ", flag); extra = print_char(f, code + 1 + IMM2_SIZE, utf); fprintf(f, "{"); if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?"); else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+"); break; case OP_TYPEEXACT: case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]); if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) { fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1], code[1 + IMM2_SIZE + 2])); extra = 2; } fprintf(f, "{"); if (*code != OP_TYPEEXACT) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+"); break; case OP_NOTI: flag = "/i"; /* Fall through */ case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); fprintf(f, "]"); break; case OP_NOTSTARI: case OP_NOTMINSTARI: case OP_NOTPOSSTARI: case OP_NOTPLUSI: case OP_NOTMINPLUSI: case OP_NOTPOSPLUSI: case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; /* Fall through */ case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPOSSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTPOSPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTPOSQUERY: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); fprintf(f, "]%s", priv_OP_names[*code]); break; case OP_NOTEXACTI: case OP_NOTUPTOI: case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; /* Fall through */ case OP_NOTEXACT: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTPOSUPTO: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1 + IMM2_SIZE, utf); fprintf(f, "]{"); if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); else if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); break; case OP_RECURSE: if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); else fprintf(f, " "); fprintf(f, "%s", priv_OP_names[*code]); break; case OP_REFI: flag = "/i"; /* Fall through */ case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); ccode = code + priv_OP_lengths[*code]; goto CLASS_REF_REPEAT; case OP_CALLOUT: fprintf(f, " %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2), GET(code, 2 + LINK_SIZE)); break; case OP_PROP: case OP_NOTPROP: fprintf(f, " %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2])); break; /* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no harm in having this code always here, and it makes it less messy without all those #ifdefs. */ case OP_CLASS: case OP_NCLASS: case OP_XCLASS: { int i, min, max; BOOL printmap; pcre_uint8 *map; fprintf(f, " ["); if (*code == OP_XCLASS) { extra = GET(code, 1); ccode = code + LINK_SIZE + 1; printmap = (*ccode & XCL_MAP) != 0; if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); } else { printmap = TRUE; ccode = code + 1; } /* Print a bit map */ if (printmap) { map = (pcre_uint8 *)ccode; for (i = 0; i < 256; i++) { if ((map[i/8] & (1 << (i&7))) != 0) { int j; for (j = i+1; j < 256; j++) if ((map[j/8] & (1 << (j&7))) == 0) break; if (i == '-' || i == ']') fprintf(f, "\\"); if (PRINTABLE(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i); if (--j > i) { if (j != i + 1) fprintf(f, "-"); if (j == '-' || j == ']') fprintf(f, "\\"); if (PRINTABLE(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j); } i = j; } } ccode += 32 / sizeof(pcre_uchar); } /* For an XCLASS there is always some additional data */ if (*code == OP_XCLASS) { int ch; while ((ch = *ccode++) != XCL_END) { if (ch == XCL_PROP) { int ptype = *ccode++; int pvalue = *ccode++; fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); } else if (ch == XCL_NOTPROP) { int ptype = *ccode++; int pvalue = *ccode++; fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue)); } else { ccode += 1 + print_char(f, ccode, utf); if (ch == XCL_RANGE) { fprintf(f, "-"); ccode += 1 + print_char(f, ccode, utf); } } } } /* Indicate a non-UTF class which was created by negation */ fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); /* Handle repeats after a class or a back reference */ CLASS_REF_REPEAT: switch(*ccode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: fprintf(f, "%s", priv_OP_names[*ccode]); extra += priv_OP_lengths[*ccode]; break; case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(ccode,1); max = GET2(ccode,1 + IMM2_SIZE); if (max == 0) fprintf(f, "{%d,}", min); else fprintf(f, "{%d,%d}", min, max); if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); extra += priv_OP_lengths[*ccode]; break; /* Do nothing if it's not a repeat; this code stops picky compilers warning about the lack of a default code path. */ default: break; } } break; case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: fprintf(f, " %s ", priv_OP_names[*code]); print_puchar(f, code + 2); extra += code[1]; break; case OP_THEN: fprintf(f, " %s", priv_OP_names[*code]); break; case OP_CIRCM: case OP_DOLLM: flag = "/m"; /* Fall through */ /* Anything else is just an item with no data, but possibly a flag. */ default: fprintf(f, " %s %s", flag, priv_OP_names[*code]); break; } code += priv_OP_lengths[*code] + extra; fprintf(f, "\n"); } } /* End of pcre_printint.src */ pcre-8.31/missing0000755000222100022210000002623311775524614010724 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2009-04-28.21; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; tar*) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar*) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: pcre-8.31/dftables.c0000644000222100022210000001516111676645217011256 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This is a freestanding support program to generate a file containing character tables for PCRE. The tables are built according to the current locale. Now that pcre_maketables is a function visible to the outside world, we make use of its code from here in order to be consistent. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "pcre_internal.h" #define DFTABLES /* pcre_maketables.c notices this */ #include "pcre_maketables.c" int main(int argc, char **argv) { FILE *f; int i = 1; const unsigned char *tables; const unsigned char *base_of_tables; /* By default, the default C locale is used rather than what the building user happens to have set. However, if the -L option is given, set the locale from the LC_xxx environment variables. */ if (argc > 1 && strcmp(argv[1], "-L") == 0) { setlocale(LC_ALL, ""); /* Set from environment variables */ i++; } if (argc < i + 1) { fprintf(stderr, "dftables: one filename argument is required\n"); return 1; } tables = pcre_maketables(); base_of_tables = tables; f = fopen(argv[i], "wb"); if (f == NULL) { fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]); return 1; } /* There are several fprintf() calls here, because gcc in pedantic mode complains about the very long string otherwise. */ fprintf(f, "/*************************************************\n" "* Perl-Compatible Regular Expressions *\n" "*************************************************/\n\n" "/* This file was automatically written by the dftables auxiliary\n" "program. It contains character tables that are used when no external\n" "tables are passed to PCRE by the application that calls it. The tables\n" "are used only for characters whose code values are less than 256.\n\n"); fprintf(f, "The following #includes are present because without them gcc 4.x may remove\n" "the array definition from the final binary if PCRE is built into a static\n" "library and dead code stripping is activated. This leads to link errors.\n" "Pulling in the header ensures that the array gets flagged as \"someone\n" "outside this compilation unit might reference this\" and so it will always\n" "be supplied to the linker. */\n\n" "#ifdef HAVE_CONFIG_H\n" "#include \"config.h\"\n" "#endif\n\n" "#include \"pcre_internal.h\"\n\n"); fprintf(f, "const pcre_uint8 PRIV(default_tables)[] = {\n\n" "/* This table is a lower casing table. */\n\n"); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); fprintf(f, "%3d", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table is a case flipping table. */\n\n"); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); fprintf(f, "%3d", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table contains bit maps for various character classes.\n" "Each map is 32 bytes long and the bits run from the least\n" "significant end of each byte. The classes that have their own\n" "maps are: space, xdigit, digit, upper, lower, word, graph\n" "print, punct, and cntrl. Other classes are built from combinations. */\n\n"); fprintf(f, " "); for (i = 0; i < cbit_length; i++) { if ((i & 7) == 0 && i != 0) { if ((i & 31) == 0) fprintf(f, "\n"); fprintf(f, "\n "); } fprintf(f, "0x%02x", *tables++); if (i != cbit_length - 1) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table identifies various classes of character by individual bits:\n" " 0x%02x white space character\n" " 0x%02x letter\n" " 0x%02x decimal digit\n" " 0x%02x hexadecimal digit\n" " 0x%02x alphanumeric or '_'\n" " 0x%02x regular expression metacharacter or binary zero\n*/\n\n", ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word, ctype_meta); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) { fprintf(f, " /* "); if (isprint(i-8)) fprintf(f, " %c -", i-8); else fprintf(f, "%3d-", i-8); if (isprint(i-1)) fprintf(f, " %c ", i-1); else fprintf(f, "%3d", i-1); fprintf(f, " */\n "); } fprintf(f, "0x%02x", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, "};/* "); if (isprint(i-8)) fprintf(f, " %c -", i-8); else fprintf(f, "%3d-", i-8); if (isprint(i-1)) fprintf(f, " %c ", i-1); else fprintf(f, "%3d", i-1); fprintf(f, " */\n\n/* End of pcre_chartables.c */\n"); fclose(f); free((void *)base_of_tables); return 0; } /* End of dftables.c */ pcre-8.31/pcregexp.pas0000644000222100022210000006272711343173723011647 00000000000000{ pcRegExp - Perl compatible regular expressions for Virtual Pascal (c) 2001 Peter S. Voronov aka Chem O'Dun Based on PCRE library interface unit for Virtual Pascal. (c) 2001 Alexander Tokarev The current PCRE version is: 3.7 This software may be distributed under the terms of the modified BSD license Copyright (c) 2001, Alexander Tokarev All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The PCRE library is written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge AngelsHolocaust 4-11-04 updated to use version v5.0 (INFO: this is regex-directed, NFA) AH: 9-11-04 - pcre_free: removed var, pcre already gives the ptr, now everything works as it should (no more crashes) -> removed CheckRegExp because pcre handles errors perfectly 10-11-04 - added pcError (errorhandling), pcInit 13-11-04 - removed the ErrorPos = 0 check -> always print erroroffset 17-10-05 - support for \1-\9 backreferences in TpcRegExp.GetReplStr 17-02-06 - added RunTimeOptions: caller can set options while searching 19-02-06 - added SearchOfs(): let PCRE use the complete string and offset into the string itself 20-12-06 - support for version 7.0 27.08.08 - support for v7.7 } {$H+} {$DEFINE PCRE_3_7} {$DEFINE PCRE_5_0} {$DEFINE PCRE_7_0} {$DEFINE PCRE_7_7} Unit pcregexp; Interface uses objects; Type PpcRegExp = ^TpcRegExp; // TpcRegExp = object TpcRegExp = object(TObject) MatchesCount: integer; RegExpC, RegExpExt : Pointer; Matches:Pointer; RegExp: shortstring; SourceLen: integer; PartialMatch : boolean; Error : boolean; ErrorMsg : Pchar; ErrorPos : integer; RunTimeOptions: Integer; // options which can be set by the caller constructor Init(const ARegExp : shortstring; AOptions : integer; ALocale : Pointer); function Search(AStr: Pchar; ALen : longint) : boolean; virtual; function SearchNext( AStr: Pchar; ALen : longint) : boolean; virtual; function SearchOfs ( AStr: Pchar; ALen, AOfs : longint) : boolean; virtual; function MatchSub(ANom: integer; var Pos, Len : longint) : boolean; virtual; function MatchFull(var Pos, Len : longint) : boolean; virtual; function GetSubStr(ANom: integer; AStr: Pchar) : string; virtual; function GetFullStr(AStr: Pchar) : string; virtual; function GetReplStr(AStr: Pchar; const ARepl: string) : string; virtual; function GetPreSubStr(AStr: Pchar) : string; virtual; function GetPostSubStr(AStr: Pchar) : string; virtual; function ErrorStr : string; virtual; destructor Done; virtual; end; function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean; function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string; function pcFastGrepMatch(WildCard, aStr: string): Boolean; function pcFastGrepSub(WildCard, aStr, aRepl: string): string; {$IFDEF PCRE_5_0} function pcGetVersion : pchar; {$ENDIF} function pcError (var pRegExp : Pointer) : Boolean; function pcInit (const Pattern: Shortstring; CaseSens: Boolean) : Pointer; Const { Options } PCRE_CASELESS = $0001; PCRE_MULTILINE = $0002; PCRE_DOTALL = $0004; PCRE_EXTENDED = $0008; PCRE_ANCHORED = $0010; PCRE_DOLLAR_ENDONLY = $0020; PCRE_EXTRA = $0040; PCRE_NOTBOL = $0080; PCRE_NOTEOL = $0100; PCRE_UNGREEDY = $0200; PCRE_NOTEMPTY = $0400; {$IFDEF PCRE_5_0} PCRE_UTF8 = $0800; PCRE_NO_AUTO_CAPTURE = $1000; PCRE_NO_UTF8_CHECK = $2000; PCRE_AUTO_CALLOUT = $4000; PCRE_PARTIAL = $8000; {$ENDIF} {$IFDEF PCRE_7_0} PCRE_DFA_SHORTEST = $00010000; PCRE_DFA_RESTART = $00020000; PCRE_FIRSTLINE = $00040000; PCRE_DUPNAMES = $00080000; PCRE_NEWLINE_CR = $00100000; PCRE_NEWLINE_LF = $00200000; PCRE_NEWLINE_CRLF = $00300000; PCRE_NEWLINE_ANY = $00400000; PCRE_NEWLINE_ANYCRLF = $00500000; PCRE_NEWLINE_BITS = PCRE_NEWLINE_CR or PCRE_NEWLINE_LF or PCRE_NEWLINE_ANY; {$ENDIF} {$IFDEF PCRE_7_7} PCRE_BSR_ANYCRLF = $00800000; PCRE_BSR_UNICODE = $01000000; PCRE_JAVASCRIPT_COMPAT= $02000000; {$ENDIF} PCRE_COMPILE_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_AUTO_CALLOUT + PCRE_CASELESS + PCRE_DOLLAR_ENDONLY + PCRE_DOTALL + PCRE_EXTENDED + PCRE_EXTRA + PCRE_MULTILINE + PCRE_NO_AUTO_CAPTURE + PCRE_UNGREEDY + PCRE_UTF8 + PCRE_NO_UTF8_CHECK {$IFDEF PCRE_7_0} + PCRE_DUPNAMES + PCRE_FIRSTLINE + PCRE_NEWLINE_BITS {$ENDIF} {$IFDEF PCRE_7_7} + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE + PCRE_JAVASCRIPT_COMPAT {$ENDIF} ; PCRE_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL + PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL {$IFDEF PCRE_7_0} + PCRE_NEWLINE_BITS {$ENDIF} {$IFDEF PCRE_7_7} + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE {$ENDIF} ; {$IFDEF PCRE_7_0} PCRE_DFA_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL + PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL + PCRE_DFA_SHORTEST + PCRE_DFA_RESTART + PCRE_NEWLINE_BITS {$IFDEF PCRE_7_7} + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE {$ENDIF} ; {$ENDIF} { Exec-time and get/set-time error codes } PCRE_ERROR_NOMATCH = -1; PCRE_ERROR_NULL = -2; PCRE_ERROR_BADOPTION = -3; PCRE_ERROR_BADMAGIC = -4; PCRE_ERROR_UNKNOWN_MODE = -5; PCRE_ERROR_NOMEMORY = -6; PCRE_ERROR_NOSUBSTRING = -7; {$IFDEF PCRE_5_0} PCRE_ERROR_MATCHLIMIT = -8; PCRE_ERROR_CALLOUT = -9; { Never used by PCRE itself } PCRE_ERROR_BADUTF8 = -10; PCRE_ERROR_BADUTF8_OFFSET = -11; PCRE_ERROR_PARTIAL = -12; PCRE_ERROR_BADPARTIAL = -13; PCRE_ERROR_INTERNAL = -14; PCRE_ERROR_BADCOUNT = -15; {$ENDIF} {$IFDEF PCRE_7_0} PCRE_ERROR_DFA_UITEM = -16; PCRE_ERROR_DFA_UCOND = -17; PCRE_ERROR_DFA_UMLIMIT = -18; PCRE_ERROR_DFA_WSSIZE = -19; PCRE_ERROR_DFA_RECURSE = -20; PCRE_ERROR_RECURSIONLIMIT = -21; PCRE_ERROR_NULLWSLIMIT = -22; PCRE_ERROR_BADNEWLINE = -23; {$ENDIF} { Request types for pcre_fullinfo() } PCRE_INFO_OPTIONS = 0; PCRE_INFO_SIZE = 1; PCRE_INFO_CAPTURECOUNT = 2; PCRE_INFO_BACKREFMAX = 3; PCRE_INFO_FIRSTBYTE = 4; PCRE_INFO_FIRSTCHAR = 4; { For backwards compatibility } PCRE_INFO_FIRSTTABLE = 5; {$IFDEF PCRE_5_0} PCRE_INFO_LASTLITERAL = 6; PCRE_INFO_NAMEENTRYSIZE = 7; PCRE_INFO_NAMECOUNT = 8; PCRE_INFO_NAMETABLE = 9; PCRE_INFO_STUDYSIZE = 10; PCRE_INFO_DEFAULT_TABLES = 11; {$ENDIF PCRE_5_0} {$IFDEF PCRE_7_7} PCRE_INFO_OKPARTIAL = 12; PCRE_INFO_JCHANGED = 13; PCRE_INFO_HASCRORLF = 14; {$ENDIF} { Request types for pcre_config() } {$IFDEF PCRE_5_0} PCRE_CONFIG_UTF8 = 0; PCRE_CONFIG_NEWLINE = 1; PCRE_CONFIG_LINK_SIZE = 2; PCRE_CONFIG_POSIX_MALLOC_THRESHOLD = 3; PCRE_CONFIG_MATCH_LIMIT = 4; PCRE_CONFIG_STACKRECURSE = 5; PCRE_CONFIG_UNICODE_PROPERTIES = 6; {$ENDIF PCRE_5_0} {$IFDEF PCRE_7_0} PCRE_CONFIG_MATCH_LIMIT_RECURSION = 7; {$ENDIF} {$IFDEF PCRE_7_7} PCRE_CONFIG_BSR = 8; {$ENDIF} { Bit flags for the pcre_extra structure } {$IFDEF PCRE_5_0} PCRE_EXTRA_STUDY_DATA = $0001; PCRE_EXTRA_MATCH_LIMIT = $0002; PCRE_EXTRA_CALLOUT_DATA = $0004; PCRE_EXTRA_TABLES = $0008; {$ENDIF PCRE_5_0} {$IFDEF PCRE_7_0} PCRE_EXTRA_MATCH_LIMIT_RECURSION = $0010; {$ENDIF} Const // DefaultOptions : integer = 0; DefaultLocaleTable : pointer = nil; {$IFDEF PCRE_5_0} { The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. } type ppcre_extra = ^tpcre_extra; tpcre_extra = record flags : longint; { Bits for which fields are set } study_data : pointer; { Opaque data from pcre_study() } match_limit : longint; { Maximum number of calls to match() } callout_data : pointer; { Data passed back in callouts } tables : pointer; { Pointer to character tables } match_limit_recursion: longint; { Max recursive calls to match() } end; type ppcre_callout_block = ^pcre_callout_block; pcre_callout_block = record version, (* ------------------------ Version 0 ------------------------------- *) callout_number : integer; offset_vector : pointer; subject : pchar; subject_length, start_match, current_position, capture_top, capture_last : integer; callout_data : pointer; (* ------------------- Added for Version 1 -------------------------- *) pattern_position, next_item_length : integer; end; {$ENDIF PCRE_5_0} {$OrgName+} {$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL} { local replacement of external pcre memory management functions } function pcre_malloc( size : integer ) : pointer; procedure pcre_free( {var} p : pointer ); {$IFDEF PCRE_5_0} const pcre_stack_malloc: function ( size : integer ): pointer = pcre_malloc; pcre_stack_free: procedure ( {var} p : pointer ) = pcre_free; function pcre_callout(var p : ppcre_callout_block) : integer; {$ENDIF PCRE_5_0} {$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL} Implementation Uses strings, collect, messages, dnapp, commands, advance0, stringsx {$IFDEF VIRTUALPASCAL} ,vpsyslow {$ENDIF VIRTUALPASCAL}; Const MAGIC_NUMBER = $50435245; { 'PCRE' } MAX_MATCHES = 90; { changed in 3.5 version; should be divisible by 3, was 64} Type PMatchArray = ^TMatchArray; TMatchArray = array[0..( MAX_MATCHES * 3 )] of integer; PRegExpCollection = ^TRegExpCollection; TRegExpCollection = object(TSortedCollection) MaxRegExp : integer; SearchRegExp : shortstring; CompareModeInsert : boolean; constructor Init(AMaxRegExp:integer); procedure FreeItem(P: Pointer); virtual; function Compare(P1, P2: Pointer): Integer; virtual; function Find(ARegExp:shortstring;var P: PpcRegExp):boolean; virtual; function CheckNew(ARegExp:shortstring):PpcRegExp;virtual; end; Var PRegExpCache : PRegExpCollection; {$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL} { imported original pcre functions } function pcre_compile( const pattern : PChar; options : integer; var errorptr : PChar; var erroroffset : integer; const tables : PChar ) : pointer {pcre}; external; {$IFDEF PCRE_7_0} function pcre_compile2( const pattern : PChar; options : integer; var errorcodeptr : Integer; var errorptr : PChar; var erroroffset : integer; const tables : PChar ) : pointer {pcre}; external; {$ENDIF} {$IFDEF PCRE_5_0} function pcre_config( what : integer; where : pointer) : integer; external; function pcre_copy_named_substring( const code : pointer {pcre}; const subject : pchar; var ovector : integer; stringcount : integer; const stringname : pchar; var buffer : pchar; size : integer) : integer; external; function pcre_copy_substring( const subject : pchar; var ovector : integer; stringcount, stringnumber : integer; var buffer : pchar; size : integer ) : integer; external; function pcre_exec( const argument_re : pointer {pcre}; const extra_data : pointer {pcre_extra}; {$ELSE} function pcre_exec( const external_re : pointer; const external_extra : pointer; {$ENDIF} const subject : PChar; length, start_offset, options : integer; offsets : pointer; offsetcount : integer ) : integer; external; {$IFDEF PCRE_7_0} function pcre_dfa_exec( const argument_re : pointer {pcre}; const extra_data : pointer {pcre_extra}; const subject : pchar; length, start_offset, options : integer; offsets : pointer; offsetcount : integer; workspace : pointer; wscount : integer ) : integer; external; {$ENDIF} {$IFDEF PCRE_5_0} procedure pcre_free_substring( const p : pchar ); external; procedure pcre_free_substring_list( var p : pchar ); external; function pcre_fullinfo( const argument_re : pointer {pcre}; const extra_data : pointer {pcre_extra}; what : integer; where : pointer ) : integer; external; function pcre_get_named_substring( const code : pointer {pcre}; const subject : pchar; var ovector : integer; stringcount : integer; const stringname : pchar; var stringptr : pchar ) : integer; external; function pcre_get_stringnumber( const code : pointer {pcre}; const stringname : pchar ) : integer; external; function pcre_get_stringtable_entries( const code : pointer {pcre}; const stringname : pchar; var firstptr, lastptr : pchar ) : integer; external; function pcre_get_substring( const subject : pchar; var ovector : integer; stringcount, stringnumber : integer; var stringptr : pchar ) : integer; external; function pcre_get_substring_list( const subject : pchar; var ovector : integer; stringcount : integer; listptr : pointer {const char ***listptr}) : integer; external; function pcre_info( const argument_re : pointer {pcre}; var optptr : integer; var first_byte : integer ) : integer; external; function pcre_maketables : pchar; external; {$ENDIF} {$IFDEF PCRE_7_0} function pcre_refcount( const argument_re : pointer {pcre}; adjust : integer ) : pchar; external; {$ENDIF} function pcre_study( const external_re : pointer {pcre}; options : integer; var errorptr : PChar ) : pointer {pcre_extra}; external; {$IFDEF PCRE_5_0} function pcre_version : pchar; external; {$ENDIF} function pcre_malloc( size : integer ) : pointer; begin GetMem( result, size ); end; procedure pcre_free( {var} p : pointer ); begin if (p <> nil) then FreeMem( p, 0 ); {@p := nil;} end; {$IFDEF PCRE_5_0} (* Called from PCRE as a result of the (?C) item. We print out where we are in the match. Yield zero unless more callouts than the fail count, or the callout data is not zero. *) function pcre_callout; begin end; {$ENDIF} {$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL} // Always include the newest version of the library {$IFDEF PCRE_7_7} {$L pcre77.lib} {$ELSE} {$IFDEF PCRE_7_0} {$L pcre70.lib} {$ELSE} {$IFDEF PCRE_5_0} {$L pcre50.lib} {$ELSE} {$IFDEF PCRE_3_7} {$L pcre37.lib} {$ENDIF PCRE_3_7} {$ENDIF PCRE_5_0} {$ENDIF PCRE_7_0} {$ENDIF PCRE_7_7} {TpcRegExp} constructor TpcRegExp.Init(const ARegExp:shortstring; AOptions:integer; ALocale : Pointer); var pRegExp : PChar; begin RegExp:=ARegExp; RegExpC:=nil; RegExpExt:=nil; Matches:=nil; MatchesCount:=0; Error:=true; ErrorMsg:=nil; ErrorPos:=0; RunTimeOptions := 0; if length(RegExp) < 255 then begin RegExp[length(RegExp)+1]:=#0; pRegExp:=@RegExp[1]; end else begin GetMem(pRegExp,length(RegExp)+1); pRegExp:=strpcopy(pRegExp,RegExp); end; RegExpC := pcre_compile( pRegExp, AOptions and PCRE_COMPILE_ALLOWED_OPTIONS, ErrorMsg, ErrorPos, ALocale); if length(RegExp) = 255 then StrDispose(pRegExp); if RegExpC = nil then exit; ErrorMsg:=nil; RegExpExt := pcre_study( RegExpC, 0, ErrorMsg ); if (RegExpExt = nil) and (ErrorMsg <> nil) then begin pcre_free(RegExpC); exit; end; GetMem(Matches,SizeOf(TMatchArray)); Error:=false; end; destructor TpcRegExp.Done; begin if RegExpC <> nil then pcre_free(RegExpC); if RegExpExt <> nil then pcre_free(RegExpExt); if Matches <> nil then FreeMem(Matches,SizeOf(TMatchArray)); end; function TpcRegExp.SearchNext( AStr: Pchar; ALen : longint ) : boolean; var Options: Integer; begin // must handle PCRE_ERROR_PARTIAL here Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and PCRE_EXEC_ALLOWED_OPTIONS; if MatchesCount > 0 then MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, PMatchArray(Matches)^[1], Options, Matches, MAX_MATCHES ) else MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, 0, Options, Matches, MAX_MATCHES ); { if MatchesCount = 0 then MatchesCount := MatchesCount div 3;} PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL; SearchNext := MatchesCount > 0; end; function TpcRegExp.Search( AStr: Pchar; ALen : longint):boolean; begin MatchesCount:=0; Search:=SearchNext(AStr,ALen); SourceLen:=ALen; end; function TpcRegExp.SearchOfs( AStr: Pchar; ALen, AOfs: longint ) : boolean; var Options: Integer; begin MatchesCount:=0; Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and PCRE_EXEC_ALLOWED_OPTIONS; MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, AOfs, Options, Matches, MAX_MATCHES ); PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL; SearchOfs := MatchesCount > 0; SourceLen := ALen-AOfs; end; function TpcRegExp.MatchSub(ANom:integer; var Pos,Len:longint):boolean; begin if (MatchesCount > 0) and (ANom <= (MatchesCount-1)) then begin ANom:=ANom*2; Pos:=PMatchArray(Matches)^[ANom]; Len:=PMatchArray(Matches)^[ANom+1]-Pos; MatchSub:=true; end else MatchSub:=false; end; function TpcRegExp.MatchFull(var Pos,Len:longint):boolean; begin MatchFull:=MatchSub(0,Pos,Len); end; function TpcRegExp.GetSubStr(ANom: integer; AStr: Pchar):string; var s: ansistring; pos,len: longint; begin s:=''; if MatchSub(ANom, pos, len) then begin setlength(s, len); Move(AStr[pos], s[1], len); end; GetSubStr:=s; end; function TpcRegExp.GetPreSubStr(AStr: Pchar):string; var s: ansistring; l: longint; begin s:=''; if (MatchesCount > 0) then begin l:=PMatchArray(Matches)^[0]-1; if l > 0 then begin setlength(s,l); Move(AStr[1],s[1],l); end; end; GetPreSubStr:=s; end; function TpcRegExp.GetPostSubStr(AStr: Pchar):string; var s: ansistring; l: longint; ANom: integer; begin s:=''; if (MatchesCount > 0) then begin ANom:=(MatchesCount-1){*2} shl 1; l:=SourceLen-PMatchArray(Matches)^[ANom+1]+1; if l > 0 then begin setlength(s,l); Move(AStr[PMatchArray(Matches)^[ANom+1]],s[1],l); end; end; GetPostSubStr:=s; end; function TpcRegExp.GetFullStr(AStr: Pchar):string; var s: ansistring; l: longint; begin GetFullStr:=GetSubStr(0,AStr); end; function TpcRegExp.GetReplStr(AStr: Pchar; const ARepl: string):string; var s: ansistring; l,i,lasti: longint; begin l:=length(ARepl); i:=1; lasti:=1; s:=''; while i <= l do begin case ARepl[i] of '\' : begin if i < l then begin s:=s+copy(ARepl,lasti,i-lasti){+ARepl[i+1]}; {AH 17-10-05 support for POSIX \1-\9 backreferences} case ARepl[i+1] of '0' : s:=s+GetFullStr(AStr); '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr); else s:=s+ARepl[i+1]; // copy the escaped character end; end; inc(i); lasti:=i+1; end; '$' : begin if i < l then begin s:=s+copy(ARepl,lasti,i-lasti); case ARepl[i+1] of '&' : s:=s+GetFullStr(AStr); '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr); '`' : s:=s+GetPreSubStr(AStr); #39 : s:=s+GetPostSubStr(AStr); end; end; inc(i); lasti:=i+1; end; end; inc(i); end; if lasti <= {AH 25-10-2004 added =, else l==1 won't work} l then s:=s+copy(ARepl,lasti,l-lasti+1); GetReplStr:=s; end; function TpcRegExp.ErrorStr:string; begin ErrorStr:=StrPas(ErrorMsg); end; {TRegExpCollection} constructor TRegExpCollection.Init(AMaxRegExp: integer); begin Inherited Init(1,1); MaxRegExp:=AMaxRegExp; CompareModeInsert:=true; end; procedure TRegExpCollection.FreeItem(P: Pointer); begin if P <> nil then begin Dispose(PpcRegExp(P),Done); end; end; function TRegExpCollection.Compare(P1, P2: Pointer): Integer; //var // l,l1,l2,i : byte; //// wPos: pchar; begin if CompareModeInsert then begin // l1:=length(PpcRegExp(P1)^.RegExp); // l2:=length(PpcRegExp(P2)^.RegExp); // if l1 > l2 then l:=l2 else // l:=l1; // for i:=1 to l do // if PpcRegExp(P1).RegExp[i] <> PpcRegExp(P2).RegExp[i] then break; // if i <=l then // Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(PpcRegExp(P2).RegExp[i]) else // Compare:=l1-l2; Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, PpcRegExp(P2).RegExp, False); end else begin // l1:=length(PpcRegExp(P1)^.RegExp); // l2:=length(SearchRegExp); // if l1 > l2 then l:=l2 else // l:=l1; // for i:=1 to l do // if PpcRegExp(P1).RegExp[i] <> SearchRegExp[i] then // begin // Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(SearchRegExp[i]); // break; // end; // if i > l then Compare:=l1-l2; Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, SearchRegExp, False); end; end; function TRegExpCollection.Find(ARegExp:shortstring;var P: PpcRegExp):boolean; var I : integer; begin CompareModeInsert:=false; SearchRegExp:=ARegExp; if Search(nil,I) then begin P:=PpcRegExp(At(I)); Find:=true; end else begin P:=nil; Find:=false; end; CompareModeInsert:=true; end; function TRegExpCollection.CheckNew(ARegExp:shortstring):PpcRegExp; var P : PpcRegExp; begin if not Find(ARegExp,P) then begin if Count = MaxRegExp then AtFree(0); P:=New(ppcRegExp,Init(ARegExp,PCRE_CASELESS,nil)); Insert(P); end; CheckNew:=P; end; function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean; var PpcRE:PpcRegExp; begin PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale)); pcGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr)); Dispose(PpcRE,Done); end; function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string; var PpcRE:PpcRegExp; begin PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale)); if PpcRE^.Search(pchar(AStr),Length(AStr)) then pcGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl) else pcGrepSub:=''; Dispose(PpcRE,Done); end; function pcFastGrepMatch(WildCard, aStr: string): Boolean; var PpcRE:PpcRegExp; begin PpcRE:=PRegExpCache^.CheckNew(WildCard); pcFastGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr)); end; function pcFastGrepSub(WildCard, aStr, aRepl: string): string; var PpcRE:PpcRegExp; begin PpcRE:=PRegExpCache^.CheckNew(WildCard); if PpcRE^.Search(pchar(AStr),Length(AStr)) then pcFastGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl) else pcFastGrepSub:=''; end; {$IFDEF PCRE_5_0} function pcGetVersion : pchar; assembler; {$FRAME-}{$USES none} asm call pcre_version end; {$ENDIF PCRE_5_0} function pcError; var P: ppcRegExp absolute pRegExp; begin Result := (P = nil) or P^.Error; If Result and (P <> nil) then begin { if P^.ErrorPos = 0 then MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"', nil,mfConfirmation+mfOkButton) else} MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"'+GetString(erRegExpCompPos), @P^.ErrorPos,mfConfirmation+mfOkButton); Dispose(P, Done); P:=nil; end; end; function pcInit; var Options : Integer; begin If CaseSens then Options := 0 else Options := PCRE_CASELESS; Result := New( PpcRegExp, Init( Pattern, {DefaultOptions} startup.MiscMultiData.cfgRegEx.DefaultOptions or Options, DefaultLocaleTable) ); end; Initialization PRegExpCache:=New(PRegExpCollection,Init(64)); Finalization Dispose(PRegExpCache,Done); End. pcre-8.31/HACKING0000644000222100022210000005014111721203135010266 00000000000000Technical Notes about PCRE -------------------------- These are very rough technical notes that record potentially useful information about PCRE internals. For information about testing PCRE, see the pcretest documentation and the comment at the head of the RunTest file. Historical note 1 ----------------- Many years ago I implemented some regular expression functions to an algorithm suggested by Martin Richards. These were not Unix-like in form, and were quite restricted in what they could do by comparison with Perl. The interesting part about the algorithm was that the amount of space required to hold the compiled form of an expression was known in advance. The code to apply an expression did not operate by backtracking, as the original Henry Spencer code and current Perl code does, but instead checked all possibilities simultaneously by keeping a list of current states and checking all of them as it advanced through the subject string. In the terminology of Jeffrey Friedl's book, it was a "DFA algorithm", though it was not a traditional Finite State Machine (FSM). When the pattern was all used up, all remaining states were possible matches, and the one matching the longest subset of the subject string was chosen. This did not necessarily maximize the individual wild portions of the pattern, as is expected in Unix and Perl-style regular expressions. Historical note 2 ----------------- 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 ------------------------- For the set of functions that form the "basic" PCRE library (which are unrelated to those mentioned above), I tried at first to invent an algorithm that used an amount of store bounded by a multiple of the number of characters in the pattern, to save on compiling time. However, because of the greater complexity in Perl regular expressions, I couldn't do this. In any case, a first pass through the pattern is helpful for other reasons. Support for 16-bit data strings ------------------------------- From release 8.30, PCRE supports 16-bit as well as 8-bit data strings, by being compilable in either 8-bit or 16-bit modes, or both. Thus, two different libraries can be created. In the description that follows, the word "short" is used for a 16-bit data quantity, and the word "unit" is used for a quantity that is a byte in 8-bit mode and a short in 16-bit mode. However, so as not to over-complicate the text, the names of PCRE functions are given in 8-bit form only. Computing the memory requirement: how it was -------------------------------------------- Up to and including release 6.7, PCRE worked by running a very degenerate first pass to calculate a maximum store size, and then a second pass to do the real compile - which might use a bit less than the predicted amount of memory. The idea was that this would turn out faster than the Henry Spencer code because the first pass is degenerate and the second pass can just store stuff straight into the vector, which it knows is big enough. Computing the memory requirement: how it is ------------------------------------------- By the time I was working on a potential 6.8 release, the degenerate first pass had become very complicated and hard to maintain. Indeed one of the early things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then I had a flash of inspiration as to how I could run the real compile function in a "fake" mode that enables it to compute how much memory it would need, while actually only ever using a few hundred bytes of working memory, and without too many tests of the mode that might slow it down. So I refactored the compiling functions to work this way. This got rid of about 600 lines of source. It should make future maintenance and development easier. As this was such a major change, I never released 6.8, instead upping the number to 7.0 (other quite major changes were also present in the 7.0 release). A side effect of this work was that the previous limit of 200 on the nesting depth of parentheses was removed. However, there is a downside: pcre_compile() runs more slowly than before (30% or more, depending on the pattern) because it is doing a full analysis of the pattern. My hope was that this would not be a big issue, and in the event, nobody has commented on it. Traditional matching function ----------------------------- The "traditional", and original, matching function is called pcre_exec(), and it implements an NFA algorithm, similar to the original Henry Spencer algorithm and the way that Perl works. This is not surprising, since it is intended to be as compatible with Perl as possible. This is the function most users of PCRE will use most of the time. From release 8.20, if PCRE is compiled with just-in-time (JIT) support, and studying a compiled pattern with JIT is successful, the JIT code is run instead of the normal pcre_exec() code, but the result is the same. Supplementary matching function ------------------------------- From PCRE 6.0, there is also a supplementary matching function called 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 do not always work in quite the same way. See the user documentation for details. The algorithm that is used for pcre_dfa_exec() is not a traditional FSM, because it may have a number of states active at one time. More work would be needed at compile time to produce a traditional FSM where only one state is ever active at once. I believe some other regex matchers work this way. Changeable options ------------------ The /i, /m, or /s options (PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL) may change in the middle of patterns. From PCRE 8.13, their processing is handled entirely at compile time by generating different opcodes for the different settings. The runtime functions do not need to keep track of an options state any more. Format of compiled patterns --------------------------- The compiled form of a pattern is a vector of units (bytes in 8-bit mode, or shorts in 16-bit mode), containing items of variable length. The first unit in an item contains an opcode, and the length of the item is either implicit in the opcode or contained in the data that follows it. In many cases listed below, LINK_SIZE data values are specified for offsets within the compiled pattern. LINK_SIZE always specifies a number of bytes. The default value for LINK_SIZE is 2, but PCRE can be compiled to use 3-byte or 4-byte values for these offsets, although this impairs the performance. (3-byte LINK_SIZE values are available only in 8-bit mode.) Specifing a LINK_SIZE larger than 2 is necessary only when patterns whose compiled length is greater than 64K are going to be processed. In this description, we assume the "normal" compilation options. Data values that are counts (e.g. for quantifiers) are always just two bytes long (one short in 16-bit mode). Opcodes with no following data ------------------------------ These items are all just one unit long OP_END end of pattern OP_ANY match any one character other than newline OP_ALLANY match any one character, including newline OP_ANYBYTE match any single byte, even in UTF-8 mode OP_SOD match start of data: \A OP_SOM, start of match (subject + offset): \G OP_SET_SOM, set start of match (\K) OP_CIRC ^ (start of data) OP_CIRCM ^ multiline mode (start of data or after newline) OP_NOT_WORD_BOUNDARY \W OP_WORD_BOUNDARY \w OP_NOT_DIGIT \D OP_DIGIT \d OP_NOT_HSPACE \H OP_HSPACE \h OP_NOT_WHITESPACE \S OP_WHITESPACE \s OP_NOT_VSPACE \V OP_VSPACE \v OP_NOT_WORDCHAR \W OP_WORDCHAR \w OP_EODN match end of data or \n at end: \Z OP_EOD match end of data: \z OP_DOLL $ (end of data, or before final newline) OP_DOLLM $ multiline mode (end of data or before newline) OP_EXTUNI match an extended Unicode character OP_ANYNL match any Unicode newline sequence OP_ACCEPT ) These are Perl 5.10's "backtracking control OP_COMMIT ) verbs". If OP_ACCEPT is inside capturing OP_FAIL ) parentheses, it may be preceded by one or more OP_PRUNE ) OP_CLOSE, followed by a 2-byte number, OP_SKIP ) indicating which parentheses must be closed. Backtracking control verbs with (optional) data ----------------------------------------------- (*THEN) without an argument generates the opcode OP_THEN and no following data. OP_MARK is followed by the mark name, preceded by a one-unit length, and followed by a binary zero. For (*PRUNE), (*SKIP), and (*THEN) with arguments, the opcodes OP_PRUNE_ARG, OP_SKIP_ARG, and OP_THEN_ARG are used, with the name following in the same format. Matching literal characters --------------------------- The OP_CHAR opcode is followed by a single character that is to be matched casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes, the character may be more than one unit long. Repeating single characters --------------------------- The common repeats (*, +, ?), when applied to a single character, use the following opcodes, which come in caseful and caseless versions: Caseful Caseless OP_STAR OP_STARI OP_MINSTAR OP_MINSTARI OP_POSSTAR OP_POSSTARI OP_PLUS OP_PLUSI OP_MINPLUS OP_MINPLUSI OP_POSPLUS OP_POSPLUSI OP_QUERY OP_QUERYI OP_MINQUERY OP_MINQUERYI OP_POSQUERY OP_POSQUERYI Each opcode is followed by the character that is to be repeated. In ASCII mode, these are two-unit items; in UTF-8 or UTF-16 modes, the length is variable. Those with "MIN" in their names are the minimizing versions. Those with "POS" in their names are possessive versions. Other repeats make use of these opcodes: Caseful Caseless OP_UPTO OP_UPTOI OP_MINUPTO OP_MINUPTOI OP_POSUPTO OP_POSUPTOI OP_EXACT OP_EXACTI Each of these is followed by a two-byte (one short) count (most significant byte first in 8-bit mode) and then the repeated character. OP_UPTO matches from 0 to the given number. A repeat with a non-zero minimum and a fixed maximum is coded as an OP_EXACT followed by an OP_UPTO (or OP_MINUPTO or OPT_POSUPTO). Repeating character types ------------------------- Repeats of things like \d are done exactly as for single characters, except that instead of a character, the opcode for the type is stored in the data unit. The opcodes are: OP_TYPESTAR OP_TYPEMINSTAR OP_TYPEPOSSTAR OP_TYPEPLUS OP_TYPEMINPLUS OP_TYPEPOSPLUS OP_TYPEQUERY OP_TYPEMINQUERY OP_TYPEPOSQUERY OP_TYPEUPTO OP_TYPEMINUPTO OP_TYPEPOSUPTO OP_TYPEEXACT 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 two units 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 three units: OP_PROP or OP_NOTPROP, and then the desired property type and value. Character classes ----------------- If there is only one character in the class, OP_CHAR or OP_CHARI is used for a positive class, and OP_NOT or OP_NOTI for a negative one (that is, for something like [^a]). Another set of 13 repeating opcodes (called OP_NOTSTAR etc.) are used for repeated, negated, single-character classes. The normal single-character opcodes (OP_STAR, etc.) are used for repeated positive single-character classes. When there is more than one character in a class and all the characters are less than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a negative one. In either case, the opcode is followed by a 32-byte (16-short) bit map containing a 1 bit for every character that is acceptable. The bits are counted from the least significant end of each unit. In caseless mode, bits for both cases are set. The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8/16 mode, subject characters with values greater than 255 can be handled correctly. For OP_CLASS they do not match, whereas for OP_NCLASS they do. For classes containing characters with values greater than 255, OP_XCLASS is used. It optionally uses a bit map (if any characters lie within it), followed by a list of pairs (for a range) and single characters. In caseless mode, both cases are explicitly listed. There is a flag character than indicates whether it is a positive or a negative class. Back references --------------- OP_REF (caseful) or OP_REFI (caseless) is followed by two bytes (one short) containing the reference number. Repeating character classes and back references ----------------------------------------------- Single-character classes are handled specially (see above). This section applies to OP_CLASS and OP_REF[I]. In both cases, the repeat information follows the base item. The matching code looks at the following opcode to see if it is one of OP_CRSTAR OP_CRMINSTAR OP_CRPLUS OP_CRMINPLUS OP_CRQUERY OP_CRMINQUERY OP_CRRANGE OP_CRMINRANGE All but the last two are just single-unit items. The others are followed by four bytes (two shorts) of data, comprising the minimum and maximum repeat counts. There are no special possessive opcodes for these repeats; a possessive repeat is compiled into an atomic group. Brackets and alternation ------------------------ A pair of non-capturing (round) brackets is wrapped round each expression at compile time, so alternation always happens in the context of brackets. [Note for North Americans: "bracket" to some English speakers, including myself, can be round, square, curly, or pointy. Hence this usage rather than "parentheses".] Non-capturing brackets use the opcode OP_BRA. Originally PCRE was limited to 99 capturing brackets and it used a different opcode for each one. From release 3.5, the limit was removed by putting the bracket number into the data for higher-numbered brackets. From release 7.0 all capturing brackets are handled this way, using the single opcode OP_CBRA. A bracket opcode is followed by LINK_SIZE bytes which give the offset to the next alternative OP_ALT or, if there aren't any branches, to the matching OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to the next one, or to the OP_KET opcode. For capturing brackets, the bracket number immediately follows the offset, always as a 2-byte (one short) item. OP_KET is used for subpatterns that do not repeat indefinitely, and OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or maximally respectively (see below for possessive repetitions). All three are followed by LINK_SIZE bytes giving (as a positive number) the offset back to the matching bracket opcode. If a subpattern is quantified such that it is permitted to match zero times, it is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are single-unit opcodes that tell the matcher that skipping the following subpattern entirely is a valid branch. In the case of the first two, not skipping the pattern is also valid (greedy and non-greedy). The third is used when a pattern has the quantifier {0,0}. It cannot be entirely discarded, because it may be called as a subroutine from elsewhere in the regex. A subpattern with an indefinite maximum repetition is replicated in the compiled data its minimum number of times (or once with OP_BRAZERO if the minimum is zero), with the final copy terminating with OP_KETRMIN or OP_KETRMAX as appropriate. A subpattern with a bounded maximum repetition is replicated in a nested fashion up to the maximum number of times, with OP_BRAZERO or OP_BRAMINZERO before each replication after the minimum, so that, for example, (abc){2,5} is compiled as (abc)(abc)((abc)((abc)(abc)?)?)?, except that each bracketed group has the same number. When a repeated subpattern has an unbounded upper limit, it is checked to see whether it could match an empty string. If this is the case, the opcode in the final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher that it needs to check for matching an empty string when it hits OP_KETRMIN or OP_KETRMAX, and if so, to break the loop. Possessive brackets ------------------- When a repeated group (capturing or non-capturing) is marked as possessive by the "+" notation, e.g. (abc)++, different opcodes are used. Their names all have POS on the end, e.g. OP_BRAPOS instead of OP_BRA and OP_SCPBRPOS instead of OP_SCBRA. The end of such a group is marked by OP_KETRPOS. If the minimum repetition is zero, the group is preceded by OP_BRAPOSZERO. Assertions ---------- Forward assertions are just like other subpatterns, but starting with one of the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion is OP_REVERSE, followed by a two byte (one short) count of the number of characters to move back the pointer in the subject string. In ASCII mode, the count is a number of units, but in UTF-8/16 mode each character may occupy more than one unit. A separate count is present in each alternative of a lookbehind assertion, allowing them to have different fixed lengths. Once-only (atomic) subpatterns ------------------------------ These are also just like other subpatterns, but they start with the opcode OP_ONCE. The check for matching an empty string in an unbounded repeat is handled entirely at runtime, so there is just this one opcode. Conditional subpatterns ----------------------- These are like other subpatterns, but they start with the opcode OP_COND, or OP_SCOND for one that might match an empty string in an unbounded repeat. If the condition is a back reference, this is stored at the start of the subpattern using the opcode OP_CREF followed by two bytes (one short) containing the reference number. OP_NCREF is used instead if the reference was generated by name (so that the runtime code knows to check for duplicate names). If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of group x" (coded as "(?(Rx)"), the group number is stored at the start of the subpattern using the opcode OP_RREF or OP_NRREF (cf OP_NCREF), and a value of zero for "the whole pattern". For a DEFINE condition, just the single unit OP_DEF is used (it has no associated data). Otherwise, a conditional subpattern always starts with one of the assertions. Recursion --------- Recursion either matches the current regex, or some subexpression. The opcode OP_RECURSE is followed by an value which is the offset to the starting bracket from the start of the whole pattern. From release 6.5, OP_RECURSE is automatically wrapped inside OP_ONCE brackets (because otherwise some patterns broke it). OP_RECURSE is also used for "subroutine" calls, even though they are not strictly a recursion. Callout ------- OP_CALLOUT is followed by one unit of data that holds a callout number in the range 0 to 254 for manual callouts, or 255 for an automatic callout. In both cases there follows a two-byte (one short) value giving the offset in the pattern to the start of the following item, and another two-byte (one short) item giving the length of the next item. Philip Hazel February 2012 pcre-8.31/pcrecpp_internal.h0000644000222100022210000000546711054242354013020 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* Copyright (c) 2005, Google Inc. All rights reserved. ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ #ifndef PCRECPP_INTERNAL_H #define PCRECPP_INTERNAL_H /* When compiling a DLL for Windows, the exported symbols have to be declared using some MS magic. I found some useful information on this web page: http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the information there, using __declspec(dllexport) without "extern" we have a definition; with "extern" we have a declaration. The settings here override the setting in pcre.h. We use: PCRECPP_EXP_DECL for declarations PCRECPP_EXP_DEFN for definitions of exported functions */ #ifndef PCRECPP_EXP_DECL # ifdef _WIN32 # ifndef PCRE_STATIC # define PCRECPP_EXP_DECL extern __declspec(dllexport) # define PCRECPP_EXP_DEFN __declspec(dllexport) # else # define PCRECPP_EXP_DECL extern # define PCRECPP_EXP_DEFN # endif # else # define PCRECPP_EXP_DECL extern # define PCRECPP_EXP_DEFN # endif #endif #endif /* PCRECPP_INTERNAL_H */ /* End of pcrecpp_internal.h */ pcre-8.31/pcre16_study.c0000644000222100022210000000417511676645217012025 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_study.c" /* End of pcre16_study.c */ pcre-8.31/pcrecpp_unittest.cc0000644000222100022210000011444511624205731013217 00000000000000// -*- coding: utf-8 -*- // // Copyright (c) 2005 - 2010, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat // // TODO: Test extractions for PartialMatch/Consume #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include /* for memset and strcmp */ #include #include #include "pcrecpp.h" using pcrecpp::StringPiece; using pcrecpp::RE; using pcrecpp::RE_Options; using pcrecpp::Hex; using pcrecpp::Octal; using pcrecpp::CRadix; static bool VERBOSE_TEST = false; // CHECK dies with a fatal error if condition is not true. It is *not* // controlled by NDEBUG, so the check will be executed regardless of // compilation mode. Therefore, it is safe to do things like: // CHECK_EQ(fp->Write(x), 4) #define CHECK(condition) do { \ if (!(condition)) { \ fprintf(stderr, "%s:%d: Check failed: %s\n", \ __FILE__, __LINE__, #condition); \ exit(1); \ } \ } while (0) #define CHECK_EQ(a, b) CHECK(a == b) static void Timing1(int num_iters) { // Same pattern lots of times RE pattern("ruby:\\d+"); StringPiece p("ruby:1234"); for (int j = num_iters; j > 0; j--) { CHECK(pattern.FullMatch(p)); } } static void Timing2(int num_iters) { // Same pattern lots of times RE pattern("ruby:(\\d+)"); int i; for (int j = num_iters; j > 0; j--) { CHECK(pattern.FullMatch("ruby:1234", &i)); CHECK_EQ(i, 1234); } } static void Timing3(int num_iters) { string text_string; for (int j = num_iters; j > 0; j--) { text_string += "this is another line\n"; } RE line_matcher(".*\n"); string line; StringPiece text(text_string); int counter = 0; while (line_matcher.Consume(&text)) { counter++; } printf("Matched %d lines\n", counter); } #if 0 // uncomment this if you have a way of defining VirtualProcessSize() static void LeakTest() { // Check for memory leaks unsigned long long initial_size = 0; for (int i = 0; i < 100000; i++) { if (i == 50000) { initial_size = VirtualProcessSize(); printf("Size after 50000: %llu\n", initial_size); } char buf[100]; // definitely big enough sprintf(buf, "pat%09d", i); RE newre(buf); } uint64 final_size = VirtualProcessSize(); printf("Size after 100000: %llu\n", final_size); const double growth = double(final_size - initial_size) / final_size; printf("Growth: %0.2f%%", growth * 100); CHECK(growth < 0.02); // Allow < 2% growth } #endif static void RadixTests() { printf("Testing hex\n"); #define CHECK_HEX(type, value) \ do { \ type v; \ CHECK(RE("([0-9a-fA-F]+)[uUlL]*").FullMatch(#value, Hex(&v))); \ CHECK_EQ(v, 0x ## value); \ CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0x" #value, CRadix(&v))); \ CHECK_EQ(v, 0x ## value); \ } while(0) CHECK_HEX(short, 2bad); CHECK_HEX(unsigned short, 2badU); CHECK_HEX(int, dead); CHECK_HEX(unsigned int, deadU); CHECK_HEX(long, 7eadbeefL); CHECK_HEX(unsigned long, deadbeefUL); #ifdef HAVE_LONG_LONG CHECK_HEX(long long, 12345678deadbeefLL); #endif #ifdef HAVE_UNSIGNED_LONG_LONG CHECK_HEX(unsigned long long, cafebabedeadbeefULL); #endif #undef CHECK_HEX printf("Testing octal\n"); #define CHECK_OCTAL(type, value) \ do { \ type v; \ CHECK(RE("([0-7]+)[uUlL]*").FullMatch(#value, Octal(&v))); \ CHECK_EQ(v, 0 ## value); \ CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0" #value, CRadix(&v))); \ CHECK_EQ(v, 0 ## value); \ } while(0) CHECK_OCTAL(short, 77777); CHECK_OCTAL(unsigned short, 177777U); CHECK_OCTAL(int, 17777777777); CHECK_OCTAL(unsigned int, 37777777777U); CHECK_OCTAL(long, 17777777777L); CHECK_OCTAL(unsigned long, 37777777777UL); #ifdef HAVE_LONG_LONG CHECK_OCTAL(long long, 777777777777777777777LL); #endif #ifdef HAVE_UNSIGNED_LONG_LONG CHECK_OCTAL(unsigned long long, 1777777777777777777777ULL); #endif #undef CHECK_OCTAL printf("Testing decimal\n"); #define CHECK_DECIMAL(type, value) \ do { \ type v; \ CHECK(RE("(-?[0-9]+)[uUlL]*").FullMatch(#value, &v)); \ CHECK_EQ(v, value); \ CHECK(RE("(-?[0-9a-fA-FxX]+)[uUlL]*").FullMatch(#value, CRadix(&v))); \ CHECK_EQ(v, value); \ } while(0) CHECK_DECIMAL(short, -1); CHECK_DECIMAL(unsigned short, 9999); CHECK_DECIMAL(int, -1000); CHECK_DECIMAL(unsigned int, 12345U); CHECK_DECIMAL(long, -10000000L); CHECK_DECIMAL(unsigned long, 3083324652U); #ifdef HAVE_LONG_LONG CHECK_DECIMAL(long long, -100000000000000LL); #endif #ifdef HAVE_UNSIGNED_LONG_LONG CHECK_DECIMAL(unsigned long long, 1234567890987654321ULL); #endif #undef CHECK_DECIMAL } static void TestReplace() { printf("Testing Replace\n"); struct ReplaceTest { const char *regexp; const char *rewrite; const char *original; const char *single; const char *global; int global_count; // the expected return value from ReplaceAll }; static const ReplaceTest tests[] = { { "(qu|[b-df-hj-np-tv-z]*)([a-z]+)", "\\2\\1ay", "the quick brown fox jumps over the lazy dogs.", "ethay quick brown fox jumps over the lazy dogs.", "ethay ickquay ownbray oxfay umpsjay overay ethay azylay ogsday.", 9 }, { "\\w+", "\\0-NOSPAM", "paul.haahr@google.com", "paul-NOSPAM.haahr@google.com", "paul-NOSPAM.haahr-NOSPAM@google-NOSPAM.com-NOSPAM", 4 }, { "^", "(START)", "foo", "(START)foo", "(START)foo", 1 }, { "^", "(START)", "", "(START)", "(START)", 1 }, { "$", "(END)", "", "(END)", "(END)", 1 }, { "b", "bb", "ababababab", "abbabababab", "abbabbabbabbabb", 5 }, { "b", "bb", "bbbbbb", "bbbbbbb", "bbbbbbbbbbbb", 6 }, { "b+", "bb", "bbbbbb", "bb", "bb", 1 }, { "b*", "bb", "bbbbbb", "bb", "bbbb", 2 }, { "b*", "bb", "aaaaa", "bbaaaaa", "bbabbabbabbabbabb", 6 }, { "b*", "bb", "aa\naa\n", "bbaa\naa\n", "bbabbabb\nbbabbabb\nbb", 7 }, { "b*", "bb", "aa\raa\r", "bbaa\raa\r", "bbabbabb\rbbabbabb\rbb", 7 }, { "b*", "bb", "aa\r\naa\r\n", "bbaa\r\naa\r\n", "bbabbabb\r\nbbabbabb\r\nbb", 7 }, // Check empty-string matching (it's tricky!) { "aa|b*", "@", "aa", "@", "@@", 2 }, { "b*|aa", "@", "aa", "@aa", "@@@", 3 }, #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", 5 }, { "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"), 9 }, #endif { "", NULL, NULL, NULL, NULL, 0 } }; #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.Replace(t->rewrite, &one)); CHECK_EQ(one, t->single); string all(t->original); const int replace_count = re.GlobalReplace(t->rewrite, &all); CHECK_EQ(all, t->global); CHECK_EQ(replace_count, t->global_count); } // 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_EQ(re.GlobalReplace("bb", &all), 9); 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_EQ(re.GlobalReplace("bb", &all), 9); 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() { printf("Testing Extract\n"); string s; CHECK(RE("(.*)@([^.]*)").Extract("\\2!\\1", "boris@kremvax.ru", &s)); CHECK_EQ(s, "kremvax!boris"); // check the RE interface as well CHECK(RE(".*").Extract("'\\0'", "foo", &s)); CHECK_EQ(s, "'foo'"); CHECK(!RE("bar").Extract("'\\0'", "baz", &s)); CHECK_EQ(s, "'foo'"); } static void TestConsume() { printf("Testing Consume\n"); string word; string s(" aaa b!@#$@#$cccc"); StringPiece input(s); RE r("\\s*(\\w+)"); // matches a word, possibly proceeded by whitespace CHECK(r.Consume(&input, &word)); CHECK_EQ(word, "aaa"); CHECK(r.Consume(&input, &word)); CHECK_EQ(word, "b"); CHECK(! r.Consume(&input, &word)); } static void TestFindAndConsume() { printf("Testing FindAndConsume\n"); string word; string s(" aaa b!@#$@#$cccc"); StringPiece input(s); RE r("(\\w+)"); // matches a word CHECK(r.FindAndConsume(&input, &word)); CHECK_EQ(word, "aaa"); CHECK(r.FindAndConsume(&input, &word)); CHECK_EQ(word, "b"); CHECK(r.FindAndConsume(&input, &word)); CHECK_EQ(word, "cccc"); CHECK(! r.FindAndConsume(&input, &word)); } static void TestMatchNumberPeculiarity() { printf("Testing match-number peculiarity\n"); string word1; string word2; string word3; RE r("(foo)|(bar)|(baz)"); CHECK(r.PartialMatch("foo", &word1, &word2, &word3)); CHECK_EQ(word1, "foo"); CHECK_EQ(word2, ""); CHECK_EQ(word3, ""); CHECK(r.PartialMatch("bar", &word1, &word2, &word3)); CHECK_EQ(word1, ""); CHECK_EQ(word2, "bar"); CHECK_EQ(word3, ""); CHECK(r.PartialMatch("baz", &word1, &word2, &word3)); CHECK_EQ(word1, ""); CHECK_EQ(word2, ""); CHECK_EQ(word3, "baz"); CHECK(!r.PartialMatch("f", &word1, &word2, &word3)); string a; CHECK(RE("(foo)|hello").FullMatch("hello", &a)); CHECK_EQ(a, ""); } static void TestRecursion() { printf("Testing recursion\n"); // Get one string that passes (sometimes), one that never does. string text_good("abcdefghijk"); string text_bad("acdefghijkl"); // According to pcretest, matching text_good against (\w+)*b // requires match_limit of at least 8192, and match_recursion_limit // of at least 37. RE_Options options_ml; options_ml.set_match_limit(8192); RE re("(\\w+)*b", options_ml); CHECK(re.PartialMatch(text_good) == true); CHECK(re.PartialMatch(text_bad) == false); CHECK(re.FullMatch(text_good) == false); CHECK(re.FullMatch(text_bad) == false); options_ml.set_match_limit(1024); RE re2("(\\w+)*b", options_ml); CHECK(re2.PartialMatch(text_good) == false); // because of match_limit CHECK(re2.PartialMatch(text_bad) == false); CHECK(re2.FullMatch(text_good) == false); CHECK(re2.FullMatch(text_bad) == false); RE_Options options_mlr; options_mlr.set_match_limit_recursion(50); RE re3("(\\w+)*b", options_mlr); CHECK(re3.PartialMatch(text_good) == true); CHECK(re3.PartialMatch(text_bad) == false); CHECK(re3.FullMatch(text_good) == false); CHECK(re3.FullMatch(text_bad) == false); options_mlr.set_match_limit_recursion(10); RE re4("(\\w+)*b", options_mlr); CHECK(re4.PartialMatch(text_good) == false); CHECK(re4.PartialMatch(text_bad) == false); CHECK(re4.FullMatch(text_good) == false); CHECK(re4.FullMatch(text_bad) == false); } // A meta-quoted string, interpreted as a pattern, should always match // the original unquoted string. static void TestQuoteMeta(string unquoted, RE_Options options = RE_Options()) { string quoted = RE::QuoteMeta(unquoted); RE re(quoted, options); CHECK(re.FullMatch(unquoted)); } // A string containing meaningful regexp characters, which is then meta- // quoted, should not generally match a string the unquoted string does. static void NegativeTestQuoteMeta(string unquoted, string should_not_match, RE_Options options = RE_Options()) { string quoted = RE::QuoteMeta(unquoted); RE re(quoted, options); CHECK(!re.FullMatch(should_not_match)); } // Tests that quoted meta characters match their original strings, // and that a few things that shouldn't match indeed do not. static void TestQuotaMetaSimple() { TestQuoteMeta("foo"); TestQuoteMeta("foo.bar"); TestQuoteMeta("foo\\.bar"); TestQuoteMeta("[1-9]"); TestQuoteMeta("1.5-2.0?"); TestQuoteMeta("\\d"); TestQuoteMeta("Who doesn't like ice cream?"); TestQuoteMeta("((a|b)c?d*e+[f-h]i)"); TestQuoteMeta("((?!)xxx).*yyy"); TestQuoteMeta("(["); TestQuoteMeta(string("foo\0bar", 7)); } static void TestQuoteMetaSimpleNegative() { NegativeTestQuoteMeta("foo", "bar"); NegativeTestQuoteMeta("...", "bar"); NegativeTestQuoteMeta("\\.", "."); NegativeTestQuoteMeta("\\.", ".."); NegativeTestQuoteMeta("(a)", "a"); NegativeTestQuoteMeta("(a|b)", "a"); NegativeTestQuoteMeta("(a|b)", "(a)"); NegativeTestQuoteMeta("(a|b)", "a|b"); NegativeTestQuoteMeta("[0-9]", "0"); NegativeTestQuoteMeta("[0-9]", "0-9"); NegativeTestQuoteMeta("[0-9]", "[9]"); NegativeTestQuoteMeta("((?!)xxx)", "xxx"); } static void TestQuoteMetaLatin1() { TestQuoteMeta("3\xb2 = 9"); } static void TestQuoteMetaUtf8() { #ifdef SUPPORT_UTF8 TestQuoteMeta("Pl\xc3\xa1\x63ido Domingo", pcrecpp::UTF8()); TestQuoteMeta("xyz", pcrecpp::UTF8()); // No fancy utf8 TestQuoteMeta("\xc2\xb0", pcrecpp::UTF8()); // 2-byte utf8 (degree symbol) TestQuoteMeta("27\xc2\xb0 degrees", pcrecpp::UTF8()); // As a middle character TestQuoteMeta("\xe2\x80\xb3", pcrecpp::UTF8()); // 3-byte utf8 (double prime) TestQuoteMeta("\xf0\x9d\x85\x9f", pcrecpp::UTF8()); // 4-byte utf8 (music note) TestQuoteMeta("27\xc2\xb0"); // Interpreted as Latin-1, but should still work NegativeTestQuoteMeta("27\xc2\xb0", // 2-byte utf (degree symbol) "27\\\xc2\\\xb0", pcrecpp::UTF8()); #endif } static void TestQuoteMetaAll() { printf("Testing QuoteMeta\n"); TestQuotaMetaSimple(); TestQuoteMetaSimpleNegative(); TestQuoteMetaLatin1(); TestQuoteMetaUtf8(); } // // Options tests contributed by // Giuseppe Maxia, CTO, Stardata s.r.l. // July 2005 // static void GetOneOptionResult( const char *option_name, const char *regex, const char *str, RE_Options options, bool full, string expected) { printf("Testing Option <%s>\n", option_name); if(VERBOSE_TEST) printf("/%s/ finds \"%s\" within \"%s\" \n", regex, expected.c_str(), str); string captured(""); if (full) RE(regex,options).FullMatch(str, &captured); else RE(regex,options).PartialMatch(str, &captured); CHECK_EQ(captured, expected); } static void TestOneOption( const char *option_name, const char *regex, const char *str, RE_Options options, bool full, bool assertive = true) { printf("Testing Option <%s>\n", option_name); if (VERBOSE_TEST) printf("'%s' %s /%s/ \n", str, (assertive? "matches" : "doesn't match"), regex); if (assertive) { if (full) CHECK(RE(regex,options).FullMatch(str)); else CHECK(RE(regex,options).PartialMatch(str)); } else { if (full) CHECK(!RE(regex,options).FullMatch(str)); else CHECK(!RE(regex,options).PartialMatch(str)); } } static void Test_CASELESS() { RE_Options options; RE_Options options2; options.set_caseless(true); TestOneOption("CASELESS (class)", "HELLO", "hello", options, false); TestOneOption("CASELESS (class2)", "HELLO", "hello", options2.set_caseless(true), false); TestOneOption("CASELESS (class)", "^[A-Z]+$", "Hello", options, false); TestOneOption("CASELESS (function)", "HELLO", "hello", pcrecpp::CASELESS(), false); TestOneOption("CASELESS (function)", "^[A-Z]+$", "Hello", pcrecpp::CASELESS(), false); options.set_caseless(false); TestOneOption("no CASELESS", "HELLO", "hello", options, false, false); } static void Test_MULTILINE() { RE_Options options; RE_Options options2; const char *str = "HELLO\n" "cruel\n" "world\n"; options.set_multiline(true); TestOneOption("MULTILINE (class)", "^cruel$", str, options, false); TestOneOption("MULTILINE (class2)", "^cruel$", str, options2.set_multiline(true), false); TestOneOption("MULTILINE (function)", "^cruel$", str, pcrecpp::MULTILINE(), false); options.set_multiline(false); TestOneOption("no MULTILINE", "^cruel$", str, options, false, false); } static void Test_DOTALL() { RE_Options options; RE_Options options2; const char *str = "HELLO\n" "cruel\n" "world"; options.set_dotall(true); TestOneOption("DOTALL (class)", "HELLO.*world", str, options, true); TestOneOption("DOTALL (class2)", "HELLO.*world", str, options2.set_dotall(true), true); TestOneOption("DOTALL (function)", "HELLO.*world", str, pcrecpp::DOTALL(), true); options.set_dotall(false); TestOneOption("no DOTALL", "HELLO.*world", str, options, true, false); } static void Test_DOLLAR_ENDONLY() { RE_Options options; RE_Options options2; const char *str = "HELLO world\n"; TestOneOption("no DOLLAR_ENDONLY", "world$", str, options, false); options.set_dollar_endonly(true); TestOneOption("DOLLAR_ENDONLY 1", "world$", str, options, false, false); TestOneOption("DOLLAR_ENDONLY 2", "world$", str, options2.set_dollar_endonly(true), false, false); } static void Test_EXTRA() { RE_Options options; const char *str = "HELLO"; options.set_extra(true); TestOneOption("EXTRA 1", "\\HELL\\O", str, options, true, false ); TestOneOption("EXTRA 2", "\\HELL\\O", str, RE_Options().set_extra(true), true, false ); options.set_extra(false); TestOneOption("no EXTRA", "\\HELL\\O", str, options, true ); } static void Test_EXTENDED() { RE_Options options; RE_Options options2; const char *str = "HELLO world"; options.set_extended(true); TestOneOption("EXTENDED (class)", "HELLO world", str, options, false, false); TestOneOption("EXTENDED (class2)", "HELLO world", str, options2.set_extended(true), false, false); TestOneOption("EXTENDED (class)", "^ HE L{2} O " "\\s+ " "\\w+ $ ", str, options, false); TestOneOption("EXTENDED (function)", "HELLO world", str, pcrecpp::EXTENDED(), false, false); TestOneOption("EXTENDED (function)", "^ HE L{2} O " "\\s+ " "\\w+ $ ", str, pcrecpp::EXTENDED(), false); options.set_extended(false); TestOneOption("no EXTENDED", "HELLO world", str, options, false); } static void Test_NO_AUTO_CAPTURE() { RE_Options options; const char *str = "HELLO world"; string captured; printf("Testing Option \n"); if (VERBOSE_TEST) printf("parentheses capture text\n"); RE re("(world|universe)$", options); CHECK(re.Extract("\\1", str , &captured)); CHECK_EQ(captured, "world"); options.set_no_auto_capture(true); printf("testing Option \n"); if (VERBOSE_TEST) printf("parentheses do not capture text\n"); re.Extract("\\1",str, &captured ); CHECK_EQ(captured, "world"); } static void Test_UNGREEDY() { RE_Options options; const char *str = "HELLO, 'this' is the 'world'"; options.set_ungreedy(true); GetOneOptionResult("UNGREEDY 1", "('.*')", str, options, false, "'this'" ); GetOneOptionResult("UNGREEDY 2", "('.*')", str, RE_Options().set_ungreedy(true), false, "'this'" ); GetOneOptionResult("UNGREEDY", "('.*?')", str, options, false, "'this' is the 'world'" ); options.set_ungreedy(false); GetOneOptionResult("no UNGREEDY", "('.*')", str, options, false, "'this' is the 'world'" ); GetOneOptionResult("no UNGREEDY", "('.*?')", str, options, false, "'this'" ); } static void Test_all_options() { const char *str = "HELLO\n" "cruel\n" "world"; RE_Options options; options.set_all_options(PCRE_CASELESS | PCRE_DOTALL); TestOneOption("all_options (CASELESS|DOTALL)", "^hello.*WORLD", str , options, false); options.set_all_options(0); TestOneOption("all_options (0)", "^hello.*WORLD", str , options, false, false); options.set_all_options(PCRE_MULTILINE | PCRE_EXTENDED); TestOneOption("all_options (MULTILINE|EXTENDED)", " ^ c r u e l $ ", str, options, false); TestOneOption("all_options (MULTILINE|EXTENDED) with constructor", " ^ c r u e l $ ", str, RE_Options(PCRE_MULTILINE | PCRE_EXTENDED), false); TestOneOption("all_options (MULTILINE|EXTENDED) with concatenation", " ^ c r u e l $ ", str, RE_Options() .set_multiline(true) .set_extended(true), false); options.set_all_options(0); TestOneOption("all_options (0)", "^ c r u e l $", str, options, false, false); } static void TestOptions() { printf("Testing Options\n"); Test_CASELESS(); Test_MULTILINE(); Test_DOTALL(); Test_DOLLAR_ENDONLY(); Test_EXTENDED(); Test_NO_AUTO_CAPTURE(); Test_UNGREEDY(); Test_EXTRA(); Test_all_options(); } static void TestConstructors() { printf("Testing constructors\n"); RE_Options options; options.set_dotall(true); const char *str = "HELLO\n" "cruel\n" "world"; RE orig("HELLO.*world", options); CHECK(orig.FullMatch(str)); RE copy1(orig); CHECK(copy1.FullMatch(str)); RE copy2("not a match"); CHECK(!copy2.FullMatch(str)); copy2 = copy1; CHECK(copy2.FullMatch(str)); copy2 = orig; CHECK(copy2.FullMatch(str)); // Make sure when we assign to ourselves, nothing bad happens orig = orig; copy1 = copy1; copy2 = copy2; CHECK(orig.FullMatch(str)); CHECK(copy1.FullMatch(str)); CHECK(copy2.FullMatch(str)); } int main(int argc, char** argv) { // Treat any flag as --help if (argc > 1 && argv[1][0] == '-') { printf("Usage: %s [timing1|timing2|timing3 num-iters]\n" " If 'timingX ###' is specified, run the given timing test\n" " with the given number of iterations, rather than running\n" " the default corectness test.\n", argv[0]); return 0; } if (argc > 1) { if ( argc == 2 || atoi(argv[2]) == 0) { printf("timing mode needs a num-iters argument\n"); return 1; } if (!strcmp(argv[1], "timing1")) Timing1(atoi(argv[2])); else if (!strcmp(argv[1], "timing2")) Timing2(atoi(argv[2])); else if (!strcmp(argv[1], "timing3")) Timing3(atoi(argv[2])); else printf("Unknown argument '%s'\n", argv[1]); return 0; } printf("PCRE C++ wrapper tests\n"); printf("Testing FullMatch\n"); int i; string s; /***** FullMatch with no args *****/ CHECK(RE("h.*o").FullMatch("hello")); CHECK(!RE("h.*o").FullMatch("othello")); // Must be anchored at front CHECK(!RE("h.*o").FullMatch("hello!")); // Must be anchored at end CHECK(RE("a*").FullMatch("aaaa")); // Fullmatch with normal op CHECK(RE("a*?").FullMatch("aaaa")); // Fullmatch with nongreedy op CHECK(RE("a*?\\z").FullMatch("aaaa")); // Two unusual ops /***** FullMatch with args *****/ // Zero-arg CHECK(RE("\\d+").FullMatch("1001")); // Single-arg CHECK(RE("(\\d+)").FullMatch("1001", &i)); CHECK_EQ(i, 1001); CHECK(RE("(-?\\d+)").FullMatch("-123", &i)); CHECK_EQ(i, -123); CHECK(!RE("()\\d+").FullMatch("10", &i)); CHECK(!RE("(\\d+)").FullMatch("1234567890123456789012345678901234567890", &i)); // Digits surrounding integer-arg CHECK(RE("1(\\d*)4").FullMatch("1234", &i)); CHECK_EQ(i, 23); CHECK(RE("(\\d)\\d+").FullMatch("1234", &i)); CHECK_EQ(i, 1); CHECK(RE("(-\\d)\\d+").FullMatch("-1234", &i)); CHECK_EQ(i, -1); CHECK(RE("(\\d)").PartialMatch("1234", &i)); CHECK_EQ(i, 1); CHECK(RE("(-\\d)").PartialMatch("-1234", &i)); CHECK_EQ(i, -1); // String-arg CHECK(RE("h(.*)o").FullMatch("hello", &s)); CHECK_EQ(s, string("ell")); // StringPiece-arg StringPiece sp; CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &sp, &i)); CHECK_EQ(sp.size(), 4); CHECK(memcmp(sp.data(), "ruby", 4) == 0); CHECK_EQ(i, 1234); // Multi-arg CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &s, &i)); CHECK_EQ(s, string("ruby")); CHECK_EQ(i, 1234); // Ignore non-void* NULL arg CHECK(RE("he(.*)lo").FullMatch("hello", (char*)NULL)); CHECK(RE("h(.*)o").FullMatch("hello", (string*)NULL)); CHECK(RE("h(.*)o").FullMatch("hello", (StringPiece*)NULL)); CHECK(RE("(.*)").FullMatch("1234", (int*)NULL)); #ifdef HAVE_LONG_LONG CHECK(RE("(.*)").FullMatch("1234567890123456", (long long*)NULL)); #endif CHECK(RE("(.*)").FullMatch("123.4567890123456", (double*)NULL)); CHECK(RE("(.*)").FullMatch("123.4567890123456", (float*)NULL)); // Fail on non-void* NULL arg if the match doesn't parse for the given type. CHECK(!RE("h(.*)lo").FullMatch("hello", &s, (char*)NULL)); CHECK(!RE("(.*)").FullMatch("hello", (int*)NULL)); CHECK(!RE("(.*)").FullMatch("1234567890123456", (int*)NULL)); CHECK(!RE("(.*)").FullMatch("hello", (double*)NULL)); CHECK(!RE("(.*)").FullMatch("hello", (float*)NULL)); // Ignored arg CHECK(RE("(\\w+)(:)(\\d+)").FullMatch("ruby:1234", &s, (void*)NULL, &i)); CHECK_EQ(s, string("ruby")); CHECK_EQ(i, 1234); // Type tests { char c; CHECK(RE("(H)ello").FullMatch("Hello", &c)); CHECK_EQ(c, 'H'); } { unsigned char c; CHECK(RE("(H)ello").FullMatch("Hello", &c)); CHECK_EQ(c, static_cast('H')); } { short v; CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100); CHECK(RE("(-?\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767); CHECK(RE("(-?\\d+)").FullMatch("-32768", &v)); CHECK_EQ(v, -32768); CHECK(!RE("(-?\\d+)").FullMatch("-32769", &v)); CHECK(!RE("(-?\\d+)").FullMatch("32768", &v)); } { unsigned short v; CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767); CHECK(RE("(\\d+)").FullMatch("65535", &v)); CHECK_EQ(v, 65535); CHECK(!RE("(\\d+)").FullMatch("65536", &v)); } { int v; static const int max_value = 0x7fffffff; static const int min_value = -max_value - 1; CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100); CHECK(RE("(-?\\d+)").FullMatch("2147483647", &v)); CHECK_EQ(v, max_value); CHECK(RE("(-?\\d+)").FullMatch("-2147483648", &v)); CHECK_EQ(v, min_value); CHECK(!RE("(-?\\d+)").FullMatch("-2147483649", &v)); CHECK(!RE("(-?\\d+)").FullMatch("2147483648", &v)); } { unsigned int v; static const unsigned int max_value = 0xfffffffful; CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(\\d+)").FullMatch("4294967295", &v)); CHECK_EQ(v, max_value); CHECK(!RE("(\\d+)").FullMatch("4294967296", &v)); } #ifdef HAVE_LONG_LONG # if defined(__MINGW__) || defined(__MINGW32__) # define LLD "%I64d" # define LLU "%I64u" # else # define LLD "%lld" # define LLU "%llu" # endif { long long v; static const long long max_value = 0x7fffffffffffffffLL; static const long long min_value = -max_value - 1; char buf[32]; // definitely big enough for a long long CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100",&v)); CHECK_EQ(v, -100); sprintf(buf, LLD, max_value); CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value); sprintf(buf, LLD, min_value); CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, min_value); sprintf(buf, LLD, max_value); assert(buf[strlen(buf)-1] != '9'); buf[strlen(buf)-1]++; CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); sprintf(buf, LLD, min_value); assert(buf[strlen(buf)-1] != '9'); buf[strlen(buf)-1]++; CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); } #endif #if defined HAVE_UNSIGNED_LONG_LONG && defined HAVE_LONG_LONG { unsigned long long v; long long v2; static const unsigned long long max_value = 0xffffffffffffffffULL; char buf[32]; // definitely big enough for a unsigned long long CHECK(RE("(-?\\d+)").FullMatch("100",&v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100",&v2)); CHECK_EQ(v2, -100); sprintf(buf, LLU, max_value); CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value); assert(buf[strlen(buf)-1] != '9'); buf[strlen(buf)-1]++; CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); } #endif { float v; CHECK(RE("(.*)").FullMatch("100", &v)); CHECK(RE("(.*)").FullMatch("-100.", &v)); CHECK(RE("(.*)").FullMatch("1e23", &v)); } { double v; CHECK(RE("(.*)").FullMatch("100", &v)); CHECK(RE("(.*)").FullMatch("-100.", &v)); CHECK(RE("(.*)").FullMatch("1e23", &v)); } // Check that matching is fully anchored CHECK(!RE("(\\d+)").FullMatch("x1001", &i)); CHECK(!RE("(\\d+)").FullMatch("1001x", &i)); CHECK(RE("x(\\d+)").FullMatch("x1001", &i)); CHECK_EQ(i, 1001); CHECK(RE("(\\d+)x").FullMatch("1001x", &i)); CHECK_EQ(i, 1001); // Braces CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcd")); CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcde")); CHECK(!RE("[0-9a-f+.-]{5,}").FullMatch("0abc")); // Complicated RE CHECK(RE("foo|bar|[A-Z]").FullMatch("foo")); CHECK(RE("foo|bar|[A-Z]").FullMatch("bar")); CHECK(RE("foo|bar|[A-Z]").FullMatch("X")); CHECK(!RE("foo|bar|[A-Z]").FullMatch("XY")); // Check full-match handling (needs '$' tacked on internally) CHECK(RE("fo|foo").FullMatch("fo")); CHECK(RE("fo|foo").FullMatch("foo")); CHECK(RE("fo|foo$").FullMatch("fo")); CHECK(RE("fo|foo$").FullMatch("foo")); CHECK(RE("foo$").FullMatch("foo")); CHECK(!RE("foo\\$").FullMatch("foo$bar")); CHECK(!RE("fo|bar").FullMatch("fox")); // Uncomment the following if we change the handling of '$' to // prevent it from matching a trailing newline if (false) { // Check that we don't get bitten by pcre's special handling of a // '\n' at the end of the string matching '$' CHECK(!RE("foo$").PartialMatch("foo\n")); } // Number of args int a[16]; CHECK(RE("").FullMatch("")); memset(a, 0, sizeof(0)); CHECK(RE("(\\d){1}").FullMatch("1", &a[0])); CHECK_EQ(a[0], 1); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)").FullMatch("12", &a[0], &a[1])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)").FullMatch("123", &a[0], &a[1], &a[2])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)").FullMatch("1234", &a[0], &a[1], &a[2], &a[3])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("12345", &a[0], &a[1], &a[2], &a[3], &a[4])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("123456", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); CHECK_EQ(a[5], 6); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("1234567", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); CHECK_EQ(a[5], 6); CHECK_EQ(a[6], 7); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)" "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch( "1234567890123456", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9], &a[10], &a[11], &a[12], &a[13], &a[14], &a[15])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); CHECK_EQ(a[5], 6); CHECK_EQ(a[6], 7); CHECK_EQ(a[7], 8); CHECK_EQ(a[8], 9); CHECK_EQ(a[9], 0); CHECK_EQ(a[10], 1); CHECK_EQ(a[11], 2); CHECK_EQ(a[12], 3); CHECK_EQ(a[13], 4); CHECK_EQ(a[14], 5); CHECK_EQ(a[15], 6); /***** PartialMatch *****/ printf("Testing PartialMatch\n"); CHECK(RE("h.*o").PartialMatch("hello")); CHECK(RE("h.*o").PartialMatch("othello")); CHECK(RE("h.*o").PartialMatch("hello!")); CHECK(RE("((((((((((((((((((((x))))))))))))))))))))").PartialMatch("x")); /***** other tests *****/ RadixTests(); TestReplace(); TestExtract(); TestConsume(); TestFindAndConsume(); TestQuoteMetaAll(); TestMatchNumberPeculiarity(); // Check the pattern() accessor { const string kPattern = "http://([^/]+)/.*"; const RE re(kPattern); CHECK_EQ(kPattern, re.pattern()); } // Check RE error field. { RE re("foo"); CHECK(re.error().empty()); // Must have no error } #ifdef SUPPORT_UTF8 // Check UTF-8 handling { printf("Testing UTF-8 handling\n"); // Three Japanese characters (nihongo) const unsigned char utf8_string[] = { 0xe6, 0x97, 0xa5, // 65e5 0xe6, 0x9c, 0xac, // 627c 0xe8, 0xaa, 0x9e, // 8a9e 0 }; const unsigned char utf8_pattern[] = { '.', 0xe6, 0x9c, 0xac, // 627c '.', 0 }; // Both should match in either mode, bytes or UTF-8 RE re_test1("........."); CHECK(re_test1.FullMatch(utf8_string)); RE re_test2("...", pcrecpp::UTF8()); CHECK(re_test2.FullMatch(utf8_string)); // Check that '.' matches one byte or UTF-8 character // according to the mode. string ss; RE re_test3("(.)"); CHECK(re_test3.PartialMatch(utf8_string, &ss)); CHECK_EQ(ss, string("\xe6")); RE re_test4("(.)", pcrecpp::UTF8()); CHECK(re_test4.PartialMatch(utf8_string, &ss)); CHECK_EQ(ss, string("\xe6\x97\xa5")); // Check that string matches itself in either mode RE re_test5(utf8_string); CHECK(re_test5.FullMatch(utf8_string)); RE re_test6(utf8_string, pcrecpp::UTF8()); CHECK(re_test6.FullMatch(utf8_string)); // Check that pattern matches string only in UTF8 mode RE re_test7(utf8_pattern); CHECK(!re_test7.FullMatch(utf8_string)); RE re_test8(utf8_pattern, pcrecpp::UTF8()); CHECK(re_test8.FullMatch(utf8_string)); } // Check that ungreedy, UTF8 regular expressions don't match when they // oughtn't -- see bug 82246. { // This code always worked. const char* pattern = "\\w+X"; const string target = "a aX"; RE match_sentence(pattern); RE match_sentence_re(pattern, pcrecpp::UTF8()); CHECK(!match_sentence.FullMatch(target)); CHECK(!match_sentence_re.FullMatch(target)); } { const char* pattern = "(?U)\\w+X"; const string target = "a aX"; RE match_sentence(pattern); RE match_sentence_re(pattern, pcrecpp::UTF8()); CHECK(!match_sentence.FullMatch(target)); CHECK(!match_sentence_re.FullMatch(target)); } #endif /* def SUPPORT_UTF8 */ printf("Testing error reporting\n"); { RE re("a\\1"); CHECK(!re.error().empty()); } { RE re("a[x"); CHECK(!re.error().empty()); } { RE re("a[z-a]"); CHECK(!re.error().empty()); } { RE re("a[[:foobar:]]"); CHECK(!re.error().empty()); } { RE re("a(b"); CHECK(!re.error().empty()); } { RE re("a\\"); CHECK(!re.error().empty()); } // Test that recursion is stopped TestRecursion(); // Test Options if (getenv("VERBOSE_TEST") != NULL) VERBOSE_TEST = true; TestOptions(); // Test the constructors TestConstructors(); // Done printf("OK\n"); return 0; } pcre-8.31/pcre_stringpiece.cc0000644000222100022210000000350210671500144013135 00000000000000// Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wilsonh@google.com (Wilson Hsieh) // #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "pcrecpp_internal.h" #include "pcre_stringpiece.h" std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece) { return (o << piece.as_string()); } pcre-8.31/pcre_jit_compile.c0000644000222100022210000070524611767400034012776 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge The machine code generator part (this module) was written by Zoltan Herczeg Copyright (c) 2010-2012 ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" #ifdef SUPPORT_JIT /* All-in-one: Since we use the JIT compiler only from here, we just include it. This way we don't need to touch the build system files. */ #define SLJIT_MALLOC(size) (PUBL(malloc))(size) #define SLJIT_FREE(ptr) (PUBL(free))(ptr) #define SLJIT_CONFIG_AUTO 1 #define SLJIT_CONFIG_STATIC 1 #define SLJIT_VERBOSE 0 #define SLJIT_DEBUG 0 #include "sljit/sljitLir.c" #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED #error Unsupported architecture #endif /* Allocate memory on the stack. Fast, but limited size. */ #define LOCAL_SPACE_SIZE 32768 #define STACK_GROWTH_RATE 8192 /* Enable to check that the allocation could destroy temporaries. */ #if defined SLJIT_DEBUG && SLJIT_DEBUG #define DESTROY_REGISTERS 1 #endif /* Short summary about the backtracking mechanism empolyed by the jit code generator: The code generator follows the recursive nature of the PERL compatible regular expressions. The basic blocks of regular expressions are condition checkers whose execute different commands depending on the result of the condition check. The relationship between the operators can be horizontal (concatenation) and vertical (sub-expression) (See struct backtrack_common for more details). 'ab' - 'a' and 'b' regexps are concatenated 'a+' - 'a' is the sub-expression of the '+' operator The condition checkers are boolean (true/false) checkers. Machine code is generated for the checker itself and for the actions depending on the result of the checker. The 'true' case is called as the try path (expected path), and the other is called as the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken branches on the try path. Greedy star operator (*) : Try path: match happens. Backtrack path: match failed. Non-greedy star operator (*?) : Try path: no need to perform a match. Backtrack path: match is required. The following example shows how the code generated for a capturing bracket with two alternatives. Let A, B, C, D are arbirary regular expressions, and we have the following regular expression: A(B|C)D The generated code will be the following: A try path '(' try path (pushing arguments to the stack) B try path ')' try path (pushing arguments to the stack) D try path return with successful match D backtrack path ')' backtrack path (If we arrived from "C" jump to the backtrack of "C") B backtrack path C expected path jump to D try path C backtrack path A backtrack path Notice, that the order of backtrack code paths are the opposite of the fast code paths. In this way the topmost value on the stack is always belong to the current backtrack code path. The backtrack path must check whether there is a next alternative. If so, it needs to jump back to the try path eventually. Otherwise it needs to clear out its own stack frame and continue the execution on the backtrack code paths. */ /* Saved stack frames: Atomic blocks and asserts require reloading the values of local variables when the backtrack mechanism performed. Because of OP_RECURSE, the locals are not necessarly known in compile time, thus we need a dynamic restore mechanism. The stack frames are stored in a chain list, and have the following format: ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] Thus we can restore the locals to a particular point in the stack. */ typedef struct jit_arguments { /* Pointers first. */ struct sljit_stack *stack; const pcre_uchar *str; const pcre_uchar *begin; const pcre_uchar *end; int *offsets; pcre_uchar *uchar_ptr; pcre_uchar *mark_ptr; /* Everything else after. */ int offsetcount; int calllimit; pcre_uint8 notbol; pcre_uint8 noteol; pcre_uint8 notempty; pcre_uint8 notempty_atstart; } jit_arguments; typedef struct executable_functions { void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; PUBL(jit_callback) callback; void *userdata; sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; } executable_functions; typedef struct jump_list { struct sljit_jump *jump; struct jump_list *next; } jump_list; enum stub_types { stack_alloc }; typedef struct stub_list { enum stub_types type; int data; struct sljit_jump *start; struct sljit_label *leave; struct stub_list *next; } stub_list; typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); /* The following structure is the key data type for the recursive code generator. It is allocated by compile_trypath, and contains the aguments for compile_backtrackpath. Must be the first member of its descendants. */ typedef struct backtrack_common { /* Concatenation stack. */ struct backtrack_common *prev; jump_list *nextbacktracks; /* Internal stack (for component operators). */ struct backtrack_common *top; jump_list *topbacktracks; /* Opcode pointer. */ pcre_uchar *cc; } backtrack_common; typedef struct assert_backtrack { backtrack_common common; jump_list *condfailed; /* Less than 0 (-1) if a frame is not needed. */ int framesize; /* Points to our private memory word on the stack. */ int localptr; /* For iterators. */ struct sljit_label *trypath; } assert_backtrack; typedef struct bracket_backtrack { backtrack_common common; /* Where to coninue if an alternative is successfully matched. */ struct sljit_label *alttrypath; /* For rmin and rmax iterators. */ struct sljit_label *recursivetrypath; /* For greedy ? operator. */ struct sljit_label *zerotrypath; /* Contains the branches of a failed condition. */ union { /* Both for OP_COND, OP_SCOND. */ jump_list *condfailed; assert_backtrack *assert; /* For OP_ONCE. -1 if not needed. */ int framesize; } u; /* Points to our private memory word on the stack. */ int localptr; } bracket_backtrack; typedef struct bracketpos_backtrack { backtrack_common common; /* Points to our private memory word on the stack. */ int localptr; /* Reverting stack is needed. */ int framesize; /* Allocated stack size. */ int stacksize; } bracketpos_backtrack; typedef struct braminzero_backtrack { backtrack_common common; struct sljit_label *trypath; } braminzero_backtrack; typedef struct iterator_backtrack { backtrack_common common; /* Next iteration. */ struct sljit_label *trypath; } iterator_backtrack; typedef struct recurse_entry { struct recurse_entry *next; /* Contains the function entry. */ struct sljit_label *entry; /* Collects the calls until the function is not created. */ jump_list *calls; /* Points to the starting opcode. */ int start; } recurse_entry; typedef struct recurse_backtrack { backtrack_common common; } recurse_backtrack; typedef struct compiler_common { struct sljit_compiler *compiler; pcre_uchar *start; /* Opcode local area direct map. */ int *localptrs; int cbraptr; /* OVector starting point. Must be divisible by 2. */ int ovector_start; /* Last known position of the requested byte. */ int req_char_ptr; /* Head of the last recursion. */ int recursive_head; /* First inspected character for partial matching. */ int start_used_ptr; /* Starting pointer for partial soft matches. */ int hit_start; /* End pointer of the first line. */ int first_line_end; /* Points to the marked string. */ int mark_ptr; /* Other */ const pcre_uint8 *fcc; sljit_w lcc; int mode; int nltype; int newline; int bsr_nltype; int endonly; BOOL has_set_som; sljit_w ctypes; sljit_uw name_table; sljit_w name_count; sljit_w name_entry_size; /* Labels and jump lists. */ struct sljit_label *partialmatchlabel; struct sljit_label *leavelabel; struct sljit_label *acceptlabel; stub_list *stubs; recurse_entry *entries; recurse_entry *currententry; jump_list *partialmatch; jump_list *leave; jump_list *accept; jump_list *calllimit; jump_list *stackalloc; jump_list *revertframes; jump_list *wordboundary; jump_list *anynewline; jump_list *hspace; jump_list *vspace; jump_list *casefulcmp; jump_list *caselesscmp; BOOL jscript_compat; #ifdef SUPPORT_UTF BOOL utf; #ifdef SUPPORT_UCP BOOL use_ucp; #endif jump_list *utfreadchar; #ifdef COMPILE_PCRE8 jump_list *utfreadtype8; #endif #endif /* SUPPORT_UTF */ #ifdef SUPPORT_UCP jump_list *getucd; #endif } compiler_common; /* For byte_sequence_compare. */ typedef struct compare_context { int length; int sourcereg; #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED int ucharptr; union { sljit_i asint; sljit_uh asushort; #ifdef COMPILE_PCRE8 sljit_ub asbyte; sljit_ub asuchars[4]; #else #ifdef COMPILE_PCRE16 sljit_uh asuchars[2]; #endif #endif } c; union { sljit_i asint; sljit_uh asushort; #ifdef COMPILE_PCRE8 sljit_ub asbyte; sljit_ub asuchars[4]; #else #ifdef COMPILE_PCRE16 sljit_uh asuchars[2]; #endif #endif } oc; #endif } compare_context; enum { frame_end = 0, frame_setstrbegin = -1, frame_setmark = -2 }; /* Undefine sljit macros. */ #undef CMP /* Used for accessing the elements of the stack. */ #define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) #define TMP1 SLJIT_TEMPORARY_REG1 #define TMP2 SLJIT_TEMPORARY_REG3 #define TMP3 SLJIT_TEMPORARY_EREG2 #define STR_PTR SLJIT_SAVED_REG1 #define STR_END SLJIT_SAVED_REG2 #define STACK_TOP SLJIT_TEMPORARY_REG2 #define STACK_LIMIT SLJIT_SAVED_REG3 #define ARGUMENTS SLJIT_SAVED_EREG1 #define CALL_COUNT SLJIT_SAVED_EREG2 #define RETURN_ADDR SLJIT_TEMPORARY_EREG1 /* Locals layout. */ /* These two locals can be used by the current opcode. */ #define LOCALS0 (0 * sizeof(sljit_w)) #define LOCALS1 (1 * sizeof(sljit_w)) /* Two local variables for possessive quantifiers (char1 cannot use them). */ #define POSSESSIVE0 (2 * sizeof(sljit_w)) #define POSSESSIVE1 (3 * sizeof(sljit_w)) /* Max limit of recursions. */ #define CALL_LIMIT (4 * sizeof(sljit_w)) /* The output vector is stored on the stack, and contains pointers to characters. The vector data is divided into two groups: the first group contains the start / end character pointers, and the second is the start pointers when the end of the capturing group has not yet reached. */ #define OVECTOR_START (common->ovector_start) #define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) #define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) #define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) #ifdef COMPILE_PCRE8 #define MOV_UCHAR SLJIT_MOV_UB #define MOVU_UCHAR SLJIT_MOVU_UB #else #ifdef COMPILE_PCRE16 #define MOV_UCHAR SLJIT_MOV_UH #define MOVU_UCHAR SLJIT_MOVU_UH #else #error Unsupported compiling mode #endif #endif /* Shortcuts. */ #define DEFINE_COMPILER \ struct sljit_compiler *compiler = common->compiler #define OP1(op, dst, dstw, src, srcw) \ sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) #define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) #define LABEL() \ sljit_emit_label(compiler) #define JUMP(type) \ sljit_emit_jump(compiler, (type)) #define JUMPTO(type, label) \ sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) #define JUMPHERE(jump) \ sljit_set_label((jump), sljit_emit_label(compiler)) #define CMP(type, src1, src1w, src2, src2w) \ sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) #define CMPTO(type, src1, src1w, src2, src2w, label) \ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) #define COND_VALUE(op, dst, dstw, type) \ sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type)) #define GET_LOCAL_BASE(dst, dstw, offset) \ sljit_get_local_base(compiler, (dst), (dstw), (offset)) static pcre_uchar* bracketend(pcre_uchar* cc) { SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); do cc += GET(cc, 1); while (*cc == OP_ALT); SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); cc += 1 + LINK_SIZE; return cc; } /* Functions whose might need modification for all new supported opcodes: next_opcode get_localspace set_localptrs get_framesize init_frame get_localsize copy_locals compile_trypath compile_backtrackpath */ static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc) { SLJIT_UNUSED_ARG(common); switch(*cc) { case OP_SOD: case OP_SOM: case OP_SET_SOM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: case OP_ALLANY: case OP_ANYNL: case OP_NOT_HSPACE: case OP_HSPACE: case OP_NOT_VSPACE: case OP_VSPACE: case OP_EXTUNI: case OP_EODN: case OP_EOD: case OP_CIRC: case OP_CIRCM: case OP_DOLL: case OP_DOLLM: case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: case OP_DEF: case OP_BRAZERO: case OP_BRAMINZERO: case OP_BRAPOSZERO: case OP_COMMIT: case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: case OP_SKIPZERO: return cc + 1; case OP_ANYBYTE: #ifdef SUPPORT_UTF if (common->utf) return NULL; #endif return cc + 1; case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: case OP_POSSTAR: case OP_POSPLUS: case OP_POSQUERY: case OP_STARI: case OP_MINSTARI: case OP_PLUSI: case OP_MINPLUSI: case OP_QUERYI: case OP_MINQUERYI: case OP_POSSTARI: case OP_POSPLUSI: case OP_POSQUERYI: case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTPOSSTAR: case OP_NOTPOSPLUS: case OP_NOTPOSQUERY: case OP_NOTSTARI: case OP_NOTMINSTARI: case OP_NOTPLUSI: case OP_NOTMINPLUSI: case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTPOSSTARI: case OP_NOTPOSPLUSI: case OP_NOTPOSQUERYI: cc += 2; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif return cc; case OP_UPTO: case OP_MINUPTO: case OP_EXACT: case OP_POSUPTO: case OP_UPTOI: case OP_MINUPTOI: case OP_EXACTI: case OP_POSUPTOI: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTEXACT: case OP_NOTPOSUPTO: case OP_NOTUPTOI: case OP_NOTMINUPTOI: case OP_NOTEXACTI: case OP_NOTPOSUPTOI: cc += 2 + IMM2_SIZE; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif return cc; case OP_NOTPROP: case OP_PROP: return cc + 1 + 2; case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSUPTO: case OP_REF: case OP_REFI: case OP_CREF: case OP_NCREF: case OP_RREF: case OP_NRREF: case OP_CLOSE: cc += 1 + IMM2_SIZE; return cc; case OP_CRRANGE: case OP_CRMINRANGE: return cc + 1 + 2 * IMM2_SIZE; case OP_CLASS: case OP_NCLASS: return cc + 1 + 32 / sizeof(pcre_uchar); #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: return cc + GET(cc, 1); #endif case OP_RECURSE: case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_REVERSE: case OP_ONCE: case OP_ONCE_NC: case OP_BRA: case OP_BRAPOS: case OP_COND: case OP_SBRA: case OP_SBRAPOS: case OP_SCOND: case OP_ALT: case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_KETRPOS: return cc + 1 + LINK_SIZE; case OP_CBRA: case OP_CBRAPOS: case OP_SCBRA: case OP_SCBRAPOS: return cc + 1 + LINK_SIZE + IMM2_SIZE; case OP_MARK: return cc + 1 + 2 + cc[1]; default: return NULL; } } static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) { int localspace = 0; pcre_uchar *alternative; /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ while (cc < ccend) { switch(*cc) { case OP_SET_SOM: common->has_set_som = TRUE; cc += 1; break; case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: case OP_ONCE_NC: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: case OP_SCOND: localspace += sizeof(sljit_w); cc += 1 + LINK_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: localspace += sizeof(sljit_w); cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_COND: /* Might be a hidden SCOND. */ alternative = cc + GET(cc, 1); if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) localspace += sizeof(sljit_w); cc += 1 + LINK_SIZE; break; case OP_RECURSE: /* Set its value only once. */ if (common->recursive_head == 0) { common->recursive_head = common->ovector_start; common->ovector_start += sizeof(sljit_w); } cc += 1 + LINK_SIZE; break; case OP_MARK: if (common->mark_ptr == 0) { common->mark_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_w); } cc += 1 + 2 + cc[1]; break; default: cc = next_opcode(common, cc); if (cc == NULL) return -1; break; } } return localspace; } static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend) { pcre_uchar *cc = common->start; pcre_uchar *alternative; while (cc < ccend) { switch(*cc) { case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: case OP_ONCE_NC: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: case OP_SCOND: common->localptrs[cc - common->start] = localptr; localptr += sizeof(sljit_w); cc += 1 + LINK_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: common->localptrs[cc - common->start] = localptr; localptr += sizeof(sljit_w); cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_COND: /* Might be a hidden SCOND. */ alternative = cc + GET(cc, 1); if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) { common->localptrs[cc - common->start] = localptr; localptr += sizeof(sljit_w); } cc += 1 + LINK_SIZE; break; default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; } } } /* Returns with -1 if no need for frame. */ static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive) { pcre_uchar *ccend = bracketend(cc); int length = 0; BOOL possessive = FALSE; BOOL setsom_found = recursive; BOOL setmark_found = recursive; if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) { length = 3; possessive = TRUE; } cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); while (cc < ccend) switch(*cc) { case OP_SET_SOM: SLJIT_ASSERT(common->has_set_som); if (!setsom_found) { length += 2; setsom_found = TRUE; } cc += 1; break; case OP_MARK: SLJIT_ASSERT(common->mark_ptr != 0); if (!setmark_found) { length += 2; setmark_found = TRUE; } cc += 1 + 2 + cc[1]; break; case OP_RECURSE: if (common->has_set_som && !setsom_found) { length += 2; setsom_found = TRUE; } if (common->mark_ptr != 0 && !setmark_found) { length += 2; setmark_found = TRUE; } cc += 1 + LINK_SIZE; break; case OP_CBRA: case OP_CBRAPOS: case OP_SCBRA: case OP_SCBRAPOS: length += 3; cc += 1 + LINK_SIZE + IMM2_SIZE; break; default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; } /* Possessive quantifiers can use a special case. */ if (SLJIT_UNLIKELY(possessive) && length == 3) return -1; if (length > 0) return length + 1; return -1; } static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive) { DEFINE_COMPILER; pcre_uchar *ccend = bracketend(cc); BOOL setsom_found = recursive; BOOL setmark_found = recursive; int offset; /* >= 1 + shortest item size (2) */ SLJIT_UNUSED_ARG(stacktop); SLJIT_ASSERT(stackpos >= stacktop + 2); stackpos = STACK(stackpos); if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); while (cc < ccend) switch(*cc) { case OP_SET_SOM: SLJIT_ASSERT(common->has_set_som); if (!setsom_found) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_w); setsom_found = TRUE; } cc += 1; break; case OP_MARK: SLJIT_ASSERT(common->mark_ptr != 0); if (!setmark_found) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_w); setmark_found = TRUE; } cc += 1 + 2 + cc[1]; break; case OP_RECURSE: if (common->has_set_som && !setsom_found) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_w); setsom_found = TRUE; } if (common->mark_ptr != 0 && !setmark_found) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_w); setmark_found = TRUE; } cc += 1 + LINK_SIZE; break; case OP_CBRA: case OP_CBRAPOS: case OP_SCBRA: case OP_SCBRAPOS: offset = (GET2(cc, 1 + LINK_SIZE)) << 1; OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); stackpos += (int)sizeof(sljit_w); cc += 1 + LINK_SIZE + IMM2_SIZE; break; default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; } OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end); SLJIT_ASSERT(stackpos == STACK(stacktop)); } static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) { int localsize = 2; pcre_uchar *alternative; /* Calculate the sum of the local variables. */ while (cc < ccend) { switch(*cc) { case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: case OP_ONCE_NC: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: case OP_SCOND: localsize++; cc += 1 + LINK_SIZE; break; case OP_CBRA: case OP_SCBRA: localsize++; cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: localsize += 2; cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_COND: /* Might be a hidden SCOND. */ alternative = cc + GET(cc, 1); if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) localsize++; cc += 1 + LINK_SIZE; break; default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; } } SLJIT_ASSERT(cc == ccend); return localsize; } static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL save, int stackptr, int stacktop) { DEFINE_COMPILER; int srcw[2]; int count; BOOL tmp1next = TRUE; BOOL tmp1empty = TRUE; BOOL tmp2empty = TRUE; pcre_uchar *alternative; enum { start, loop, end } status; status = save ? start : loop; stackptr = STACK(stackptr - 2); stacktop = STACK(stacktop - 1); if (!save) { stackptr += sizeof(sljit_w); if (stackptr < stacktop) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); stackptr += sizeof(sljit_w); tmp1empty = FALSE; } if (stackptr < stacktop) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); stackptr += sizeof(sljit_w); tmp2empty = FALSE; } /* The tmp1next must be TRUE in either way. */ } while (status != end) { count = 0; switch(status) { case start: SLJIT_ASSERT(save && common->recursive_head != 0); count = 1; srcw[0] = common->recursive_head; status = loop; break; case loop: if (cc >= ccend) { status = end; break; } switch(*cc) { case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: case OP_ONCE_NC: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: case OP_SCOND: count = 1; srcw[0] = PRIV_DATA(cc); SLJIT_ASSERT(srcw[0] != 0); cc += 1 + LINK_SIZE; break; case OP_CBRA: case OP_SCBRA: count = 1; srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: count = 2; srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); srcw[0] = PRIV_DATA(cc); SLJIT_ASSERT(srcw[0] != 0); cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_COND: /* Might be a hidden SCOND. */ alternative = cc + GET(cc, 1); if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) { count = 1; srcw[0] = PRIV_DATA(cc); SLJIT_ASSERT(srcw[0] != 0); } cc += 1 + LINK_SIZE; break; default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; } break; case end: SLJIT_ASSERT_STOP(); break; } while (count > 0) { count--; if (save) { if (tmp1next) { if (!tmp1empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); stackptr += sizeof(sljit_w); } OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); tmp1empty = FALSE; tmp1next = FALSE; } else { if (!tmp2empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); stackptr += sizeof(sljit_w); } OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); tmp2empty = FALSE; tmp1next = TRUE; } } else { if (tmp1next) { SLJIT_ASSERT(!tmp1empty); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0); tmp1empty = stackptr >= stacktop; if (!tmp1empty) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); stackptr += sizeof(sljit_w); } tmp1next = FALSE; } else { SLJIT_ASSERT(!tmp2empty); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0); tmp2empty = stackptr >= stacktop; if (!tmp2empty) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); stackptr += sizeof(sljit_w); } tmp1next = TRUE; } } } } if (save) { if (tmp1next) { if (!tmp1empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); stackptr += sizeof(sljit_w); } if (!tmp2empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); stackptr += sizeof(sljit_w); } } else { if (!tmp2empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); stackptr += sizeof(sljit_w); } if (!tmp1empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); stackptr += sizeof(sljit_w); } } } SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); } static SLJIT_INLINE BOOL ispowerof2(unsigned int value) { return (value & (value - 1)) == 0; } static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) { while (list) { /* sljit_set_label is clever enough to do nothing if either the jump or the label is NULL */ sljit_set_label(list->jump, label); list = list->next; } } static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump) { jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); if (list_item) { list_item->next = *list; list_item->jump = jump; *list = list_item; } } static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start) { DEFINE_COMPILER; stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); if (list_item) { list_item->type = type; list_item->data = data; list_item->start = start; list_item->leave = LABEL(); list_item->next = common->stubs; common->stubs = list_item; } } static void flush_stubs(compiler_common *common) { DEFINE_COMPILER; stub_list* list_item = common->stubs; while (list_item) { JUMPHERE(list_item->start); switch(list_item->type) { case stack_alloc: add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); break; } JUMPTO(SLJIT_JUMP, list_item->leave); list_item = list_item->next; } common->stubs = NULL; } static SLJIT_INLINE void decrease_call_count(compiler_common *common) { DEFINE_COMPILER; OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); } static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) { /* May destroy all locals and registers except TMP2. */ DEFINE_COMPILER; OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); #ifdef DESTROY_REGISTERS OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); #endif add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); } static SLJIT_INLINE void free_stack(compiler_common *common, int size) { DEFINE_COMPILER; OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); } static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) { DEFINE_COMPILER; struct sljit_label *loop; int i; /* At this point we can freely use all temporary registers. */ /* TMP1 returns with begin - 1. */ OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); if (length < 8) { for (i = 0; i < length; i++) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0); } else { GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); loop = LABEL(); OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, loop); } } static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) { DEFINE_COMPILER; struct sljit_label *loop; struct sljit_jump *earlyexit; /* At this point we can freely use all registers. */ OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0); OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); /* Unlikely, but possible */ earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); loop = LABEL(); OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0); OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w)); /* Copy the integer value to the output buffer */ #ifdef COMPILE_PCRE16 OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); #endif OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, loop); JUMPHERE(earlyexit); /* Calculate the return value, which is the maximum ovector value. */ if (topbracket > 1) { GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ loop = LABEL(); OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); } else OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); } static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave) { DEFINE_COMPILER; SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave); /* Store match begin and end. */ OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); #ifdef COMPILE_PCRE16 OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); #endif OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0); #ifdef COMPILE_PCRE16 OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); #endif OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0); JUMPTO(SLJIT_JUMP, leave); } static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) { /* May destroy TMP1. */ DEFINE_COMPILER; struct sljit_jump *jump; if (common->mode == JIT_PARTIAL_SOFT_COMPILE) { /* The value of -1 must be kept for start_used_ptr! */ OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1); /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); JUMPHERE(jump); } else if (common->mode == JIT_PARTIAL_HARD_COMPILE) { jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); JUMPHERE(jump); } } static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc) { /* Detects if the character has an othercase. */ unsigned int c; #ifdef SUPPORT_UTF if (common->utf) { GETCHAR(c, cc); if (c > 127) { #ifdef SUPPORT_UCP return c != UCD_OTHERCASE(c); #else return FALSE; #endif } #ifndef COMPILE_PCRE8 return common->fcc[c] != c; #endif } else #endif c = *cc; return MAX_255(c) ? common->fcc[c] != c : FALSE; } static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c) { /* Returns with the othercase. */ #ifdef SUPPORT_UTF if (common->utf && c > 127) { #ifdef SUPPORT_UCP return UCD_OTHERCASE(c); #else return c; #endif } #endif return TABLE_GET(c, common->fcc, c); } static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc) { /* Detects if the character and its othercase has only 1 bit difference. */ unsigned int c, oc, bit; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 int n; #endif #ifdef SUPPORT_UTF if (common->utf) { GETCHAR(c, cc); if (c <= 127) oc = common->fcc[c]; else { #ifdef SUPPORT_UCP oc = UCD_OTHERCASE(c); #else oc = c; #endif } } else { c = *cc; oc = TABLE_GET(c, common->fcc, c); } #else c = *cc; oc = TABLE_GET(c, common->fcc, c); #endif SLJIT_ASSERT(c != oc); bit = c ^ oc; /* Optimized for English alphabet. */ if (c <= 127 && bit == 0x20) return (0 << 8) | 0x20; /* Since c != oc, they must have at least 1 bit difference. */ if (!ispowerof2(bit)) return 0; #ifdef COMPILE_PCRE8 #ifdef SUPPORT_UTF if (common->utf && c > 127) { n = GET_EXTRALEN(*cc); while ((bit & 0x3f) == 0) { n--; bit >>= 6; } return (n << 8) | bit; } #endif /* SUPPORT_UTF */ return (0 << 8) | bit; #else /* COMPILE_PCRE8 */ #ifdef COMPILE_PCRE16 #ifdef SUPPORT_UTF if (common->utf && c > 65535) { if (bit >= (1 << 10)) bit >>= 10; else return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8)); } #endif /* SUPPORT_UTF */ return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ } static void check_partial(compiler_common *common, BOOL force) { /* Checks whether a partial matching is occured. Does not modify registers. */ DEFINE_COMPILER; struct sljit_jump *jump = NULL; SLJIT_ASSERT(!force || common->mode != JIT_COMPILE); if (common->mode == JIT_COMPILE) return; if (!force) jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); if (common->mode == JIT_PARTIAL_SOFT_COMPILE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); else { if (common->partialmatchlabel != NULL) JUMPTO(SLJIT_JUMP, common->partialmatchlabel); else add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); } if (jump != NULL) JUMPHERE(jump); } static struct sljit_jump *check_str_end(compiler_common *common) { /* Does not affect registers. Usually used in a tight spot. */ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_jump *nohit; struct sljit_jump *return_value; if (common->mode == JIT_COMPILE) return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); if (common->mode == JIT_PARTIAL_SOFT_COMPILE) { nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); JUMPHERE(nohit); return_value = JUMP(SLJIT_JUMP); } else { return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); if (common->partialmatchlabel != NULL) JUMPTO(SLJIT_JUMP, common->partialmatchlabel); else add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); } JUMPHERE(jump); return return_value; } static void detect_partial_match(compiler_common *common, jump_list **backtracks) { DEFINE_COMPILER; struct sljit_jump *jump; if (common->mode == JIT_COMPILE) { add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); return; } /* Partial matching mode. */ jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); if (common->mode == JIT_PARTIAL_SOFT_COMPILE) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); } else { if (common->partialmatchlabel != NULL) JUMPTO(SLJIT_JUMP, common->partialmatchlabel); else add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); } JUMPHERE(jump); } static void read_char(compiler_common *common) { /* Reads the character into TMP1, updates STR_PTR. Does not check STR_END. TMP2 Destroyed. */ DEFINE_COMPILER; #ifdef SUPPORT_UTF struct sljit_jump *jump; #endif OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); #ifdef SUPPORT_UTF if (common->utf) { #ifdef COMPILE_PCRE8 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); #else #ifdef COMPILE_PCRE16 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); #endif #endif /* COMPILE_PCRE8 */ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); JUMPHERE(jump); } #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } static void peek_char(compiler_common *common) { /* Reads the character into TMP1, keeps STR_PTR. Does not check STR_END. TMP2 Destroyed. */ DEFINE_COMPILER; #ifdef SUPPORT_UTF struct sljit_jump *jump; #endif OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); #ifdef SUPPORT_UTF if (common->utf) { #ifdef COMPILE_PCRE8 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); #else #ifdef COMPILE_PCRE16 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); #endif #endif /* COMPILE_PCRE8 */ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); JUMPHERE(jump); } #endif } static void read_char8_type(compiler_common *common) { /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ DEFINE_COMPILER; #if defined SUPPORT_UTF || defined COMPILE_PCRE16 struct sljit_jump *jump; #endif #ifdef SUPPORT_UTF if (common->utf) { OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #ifdef COMPILE_PCRE8 /* This can be an extra read in some situations, but hopefully it is needed in most cases. */ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); JUMPHERE(jump); #else #ifdef COMPILE_PCRE16 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); JUMPHERE(jump); /* Skip low surrogate if necessary. */ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); #endif #endif /* COMPILE_PCRE8 */ return; } #endif OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #ifdef COMPILE_PCRE16 /* The ctypes array contains only 256 values. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); #endif OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); #ifdef COMPILE_PCRE16 JUMPHERE(jump); #endif } static void skip_char_back(compiler_common *common) { /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ DEFINE_COMPILER; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 struct sljit_label *label; if (common->utf) { label = LABEL(); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); return; } #endif #if defined SUPPORT_UTF && defined COMPILE_PCRE16 if (common->utf) { OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); /* Skip low surrogate if necessary. */ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); return; } #endif OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue) { /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ DEFINE_COMPILER; if (nltype == NLTYPE_ANY) { add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); } else if (nltype == NLTYPE_ANYCRLF) { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); } else { SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); } } #ifdef SUPPORT_UTF #ifdef COMPILE_PCRE8 static void do_utfreadchar(compiler_common *common) { /* Fast decoding a UTF-8 character. TMP1 contains the first byte of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */ DEFINE_COMPILER; struct sljit_jump *jump; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); /* Searching for the first zero. */ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); jump = JUMP(SLJIT_C_NOT_ZERO); /* Two byte sequence. */ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10); jump = JUMP(SLJIT_C_NOT_ZERO); /* Three byte sequence. */ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); /* Four byte sequence. */ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3)); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } static void do_utfreadtype8(compiler_common *common) { /* Fast decoding a UTF-8 character type. TMP2 contains the first byte of the character (>= 0xc0). Return value in TMP1. */ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_jump *compare; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); jump = JUMP(SLJIT_C_NOT_ZERO); /* Two byte sequence. */ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(compare); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); /* We only have types for characters less than 256. */ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #else /* COMPILE_PCRE8 */ #ifdef COMPILE_PCRE16 static void do_utfreadchar(compiler_common *common) { /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */ DEFINE_COMPILER; struct sljit_jump *jump; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00); /* Do nothing, only return. */ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); /* Combine two 16 bit characters. */ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ #endif /* SUPPORT_UTF */ #ifdef SUPPORT_UCP /* UCD_BLOCK_SIZE must be 128 (see the assert below). */ #define UCD_BLOCK_MASK 127 #define UCD_BLOCK_SHIFT 7 static void do_getucd(compiler_common *common) { /* Search the UCD record for the character comes in TMP1. Returns chartype in TMP1 and UCD offset in TMP2. */ DEFINE_COMPILER; SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2)); OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #endif static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline) { DEFINE_COMPILER; struct sljit_label *mainloop; struct sljit_label *newlinelabel = NULL; struct sljit_jump *start; struct sljit_jump *end = NULL; struct sljit_jump *nl = NULL; #ifdef SUPPORT_UTF struct sljit_jump *singlechar; #endif jump_list *newline = NULL; BOOL newlinecheck = FALSE; BOOL readuchar = FALSE; if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) newlinecheck = TRUE; if (firstline) { /* Search for the end of the first line. */ SLJIT_ASSERT(common->first_line_end != 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { mainloop = LABEL(); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } else { end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); mainloop = LABEL(); /* Continual stores does not cause data dependency. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); read_char(common); check_newlinechar(common, common->nltype, &newline, TRUE); CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); set_jumps(newline, LABEL()); } JUMPHERE(end); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); } start = JUMP(SLJIT_JUMP); if (newlinecheck) { newlinelabel = LABEL(); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); #ifdef COMPILE_PCRE16 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); nl = JUMP(SLJIT_JUMP); } mainloop = LABEL(); /* Increasing the STR_PTR here requires one less jump in the most common case. */ #ifdef SUPPORT_UTF if (common->utf) readuchar = TRUE; #endif if (newlinecheck) readuchar = TRUE; if (readuchar) OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); if (newlinecheck) CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (common->utf) { singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(singlechar); } #endif #if defined SUPPORT_UTF && defined COMPILE_PCRE16 if (common->utf) { singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(singlechar); } #endif JUMPHERE(start); if (newlinecheck) { JUMPHERE(end); JUMPHERE(nl); } return mainloop; } static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline) { DEFINE_COMPILER; struct sljit_label *start; struct sljit_jump *leave; struct sljit_jump *found; pcre_uchar oc, bit; if (firstline) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); } start = LABEL(); leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); oc = first_char; if (caseless) { oc = TABLE_GET(first_char, common->fcc, first_char); #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) if (first_char > 127 && common->utf) oc = UCD_OTHERCASE(first_char); #endif } if (first_char == oc) found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char); else { bit = first_char ^ oc; if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); } else { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); found = JUMP(SLJIT_C_NOT_ZERO); } } OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (common->utf) { CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } #endif #if defined SUPPORT_UTF && defined COMPILE_PCRE16 if (common->utf) { CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } #endif JUMPTO(SLJIT_JUMP, start); JUMPHERE(found); JUMPHERE(leave); if (firstline) OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); } static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline) { DEFINE_COMPILER; struct sljit_label *loop; struct sljit_jump *lastchar; struct sljit_jump *firstchar; struct sljit_jump *leave; struct sljit_jump *foundcr = NULL; struct sljit_jump *notfoundnl; jump_list *newline = NULL; if (firstline) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); } if (common->nltype == NLTYPE_FIXED && common->newline > 255) { lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL); #ifdef COMPILE_PCRE16 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); #endif OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); loop = LABEL(); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); JUMPHERE(leave); JUMPHERE(firstchar); JUMPHERE(lastchar); if (firstline) OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); return; } OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); skip_char_back(common); loop = LABEL(); read_char(common); lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); check_newlinechar(common, common->nltype, &newline, FALSE); set_jumps(newline, loop); if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) { leave = JUMP(SLJIT_JUMP); JUMPHERE(foundcr); notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); #ifdef COMPILE_PCRE16 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(notfoundnl); JUMPHERE(leave); } JUMPHERE(lastchar); JUMPHERE(firstchar); if (firstline) OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); } static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline) { DEFINE_COMPILER; struct sljit_label *start; struct sljit_jump *leave; struct sljit_jump *found; #ifndef COMPILE_PCRE8 struct sljit_jump *jump; #endif if (firstline) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); } start = LABEL(); leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); #ifdef SUPPORT_UTF if (common->utf) OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); #endif #ifndef COMPILE_PCRE8 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); JUMPHERE(jump); #endif OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); found = JUMP(SLJIT_C_NOT_ZERO); #ifdef SUPPORT_UTF if (common->utf) OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (common->utf) { CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } #endif #if defined SUPPORT_UTF && defined COMPILE_PCRE16 if (common->utf) { CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } #endif JUMPTO(SLJIT_JUMP, start); JUMPHERE(found); JUMPHERE(leave); if (firstline) OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); } static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar) { DEFINE_COMPILER; struct sljit_label *loop; struct sljit_jump *toolong; struct sljit_jump *alreadyfound; struct sljit_jump *found; struct sljit_jump *foundoc = NULL; struct sljit_jump *notfound; pcre_uchar oc, bit; SLJIT_ASSERT(common->req_char_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr); OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX); toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); if (has_firstchar) OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); else OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); loop = LABEL(); notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); oc = req_char; if (caseless) { oc = TABLE_GET(req_char, common->fcc, req_char); #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) if (req_char > 127 && common->utf) oc = UCD_OTHERCASE(req_char); #endif } if (req_char == oc) found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); else { bit = req_char ^ oc; if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); } else { found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc); } } OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); JUMPTO(SLJIT_JUMP, loop); JUMPHERE(found); if (foundoc) JUMPHERE(foundoc); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0); JUMPHERE(alreadyfound); JUMPHERE(toolong); return notfound; } static void do_revertframes(compiler_common *common) { DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_label *mainloop; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); GET_LOCAL_BASE(TMP3, 0, 0); /* Drop frames until we reach STACK_TOP. */ mainloop = LABEL(); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w)); JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); /* End of dropping frames. */ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin); /* Set string begin. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); if (common->mark_ptr != 0) { jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); } /* Unknown command. */ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); JUMPTO(SLJIT_JUMP, mainloop); } static void check_wordboundary(compiler_common *common) { DEFINE_COMPILER; struct sljit_jump *skipread; #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF struct sljit_jump *jump; #endif SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); /* Get type of the previous char, and put it to LOCALS1. */ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); skip_char_back(common); check_start_used_ptr(common); read_char(common); /* Testing char type. */ #ifdef SUPPORT_UCP if (common->use_ucp) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); JUMPHERE(jump); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); } else #endif { #ifndef COMPILE_PCRE8 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); #elif defined SUPPORT_UTF /* Here LOCALS1 has already been zeroed. */ jump = NULL; if (common->utf) jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif /* COMPILE_PCRE8 */ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); #ifndef COMPILE_PCRE8 JUMPHERE(jump); #elif defined SUPPORT_UTF if (jump != NULL) JUMPHERE(jump); #endif /* COMPILE_PCRE8 */ } JUMPHERE(skipread); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); skipread = check_str_end(common); peek_char(common); /* Testing char type. This is a code duplication. */ #ifdef SUPPORT_UCP if (common->use_ucp) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); JUMPHERE(jump); } else #endif { #ifndef COMPILE_PCRE8 /* TMP2 may be destroyed by peek_char. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); #elif defined SUPPORT_UTF OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); jump = NULL; if (common->utf) jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); #ifndef COMPILE_PCRE8 JUMPHERE(jump); #elif defined SUPPORT_UTF if (jump != NULL) JUMPHERE(jump); #endif /* COMPILE_PCRE8 */ } JUMPHERE(skipread); OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); } static void check_anynewline(compiler_common *common) { /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); #if defined SUPPORT_UTF || defined COMPILE_PCRE16 #ifdef COMPILE_PCRE8 if (common->utf) { #endif COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); #ifdef COMPILE_PCRE8 } #endif #endif /* SUPPORT_UTF || COMPILE_PCRE16 */ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } static void check_hspace(compiler_common *common) { /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); #if defined SUPPORT_UTF || defined COMPILE_PCRE16 #ifdef COMPILE_PCRE8 if (common->utf) { #endif COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); #ifdef COMPILE_PCRE8 } #endif #endif /* SUPPORT_UTF || COMPILE_PCRE16 */ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } static void check_vspace(compiler_common *common) { /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); #if defined SUPPORT_UTF || defined COMPILE_PCRE16 #ifdef COMPILE_PCRE8 if (common->utf) { #endif COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); #ifdef COMPILE_PCRE8 } #endif #endif /* SUPPORT_UTF || COMPILE_PCRE16 */ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #define CHAR1 STR_END #define CHAR2 STACK_TOP static void do_casefulcmp(compiler_common *common) { DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_label *label; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); label = LABEL(); OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); JUMPTO(SLJIT_C_NOT_ZERO, label); JUMPHERE(jump); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0); OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #define LCC_TABLE STACK_LIMIT static void do_caselesscmp(compiler_common *common) { DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_label *label; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0); OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); label = LABEL(); OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); #ifndef COMPILE_PCRE8 jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255); #endif OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); #ifndef COMPILE_PCRE8 JUMPHERE(jump); jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255); #endif OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); #ifndef COMPILE_PCRE8 JUMPHERE(jump); #endif jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); JUMPTO(SLJIT_C_NOT_ZERO, label); JUMPHERE(jump); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0); OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #undef LCC_TABLE #undef CHAR1 #undef CHAR2 #if defined SUPPORT_UTF && defined SUPPORT_UCP static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1) { /* This function would be ineffective to do in JIT level. */ int c1, c2; const pcre_uchar *src2 = args->uchar_ptr; const pcre_uchar *end2 = args->end; while (src1 < end1) { if (src2 >= end2) return (pcre_uchar*)1; GETCHARINC(c1, src1); GETCHARINC(c2, src2); if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL; } return src2; } #endif /* SUPPORT_UTF && SUPPORT_UCP */ static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc, compare_context* context, jump_list **backtracks) { DEFINE_COMPILER; unsigned int othercasebit = 0; pcre_uchar *othercasechar = NULL; #ifdef SUPPORT_UTF int utflength; #endif if (caseless && char_has_othercase(common, cc)) { othercasebit = char_get_othercase_bit(common, cc); SLJIT_ASSERT(othercasebit); /* Extracting bit difference info. */ #ifdef COMPILE_PCRE8 othercasechar = cc + (othercasebit >> 8); othercasebit &= 0xff; #else #ifdef COMPILE_PCRE16 othercasechar = cc + (othercasebit >> 9); if ((othercasebit & 0x100) != 0) othercasebit = (othercasebit & 0xff) << 8; else othercasebit &= 0xff; #endif #endif } if (context->sourcereg == -1) { #ifdef COMPILE_PCRE8 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else if (context->length >= 2) OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); #else #ifdef COMPILE_PCRE16 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); #endif #endif /* COMPILE_PCRE8 */ context->sourcereg = TMP2; } #ifdef SUPPORT_UTF utflength = 1; if (common->utf && HAS_EXTRALEN(*cc)) utflength += GET_EXTRALEN(*cc); do { #endif context->length -= IN_UCHARS(1); #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED /* Unaligned read is supported. */ if (othercasebit != 0 && othercasechar == cc) { context->c.asuchars[context->ucharptr] = *cc | othercasebit; context->oc.asuchars[context->ucharptr] = othercasebit; } else { context->c.asuchars[context->ucharptr] = *cc; context->oc.asuchars[context->ucharptr] = 0; } context->ucharptr++; #ifdef COMPILE_PCRE8 if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) #else if (context->ucharptr >= 2 || context->length == 0) #endif { if (context->length >= 4) OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #ifdef COMPILE_PCRE8 else if (context->length >= 2) OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); else if (context->length >= 1) OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #else else if (context->length >= 2) OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #endif context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; switch(context->ucharptr) { case 4 / sizeof(pcre_uchar): if (context->oc.asint != 0) OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); break; case 2 / sizeof(pcre_uchar): if (context->oc.asushort != 0) OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); break; #ifdef COMPILE_PCRE8 case 1: if (context->oc.asbyte != 0) OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); break; #endif default: SLJIT_ASSERT_STOP(); break; } context->ucharptr = 0; } #else /* Unaligned read is unsupported. */ #ifdef COMPILE_PCRE8 if (context->length > 0) OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #else if (context->length > 0) OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #endif context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; if (othercasebit != 0 && othercasechar == cc) { OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); } else add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); #endif cc++; #ifdef SUPPORT_UTF utflength--; } while (utflength > 0); #endif return cc; } #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 #define SET_TYPE_OFFSET(value) \ if ((value) != typeoffset) \ { \ if ((value) > typeoffset) \ OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ else \ OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ } \ typeoffset = (value); #define SET_CHAR_OFFSET(value) \ if ((value) != charoffset) \ { \ if ((value) > charoffset) \ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \ else \ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \ } \ charoffset = (value); static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) { DEFINE_COMPILER; jump_list *found = NULL; jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks; unsigned int c; int compares; struct sljit_jump *jump = NULL; pcre_uchar *ccbegin; #ifdef SUPPORT_UCP BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; BOOL charsaved = FALSE; int typereg = TMP1, scriptreg = TMP1; unsigned int typeoffset; #endif int invertcmp, numberofcmps; unsigned int charoffset; /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ detect_partial_match(common, backtracks); read_char(common); if ((*cc++ & XCL_MAP) != 0) { OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); #ifndef COMPILE_PCRE8 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); #elif defined SUPPORT_UTF if (common->utf) jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); #ifndef COMPILE_PCRE8 JUMPHERE(jump); #elif defined SUPPORT_UTF if (common->utf) JUMPHERE(jump); #endif OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); #ifdef SUPPORT_UCP charsaved = TRUE; #endif cc += 32 / sizeof(pcre_uchar); } /* Scanning the necessary info. */ ccbegin = cc; compares = 0; while (*cc != XCL_END) { compares++; if (*cc == XCL_SINGLE) { cc += 2; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif #ifdef SUPPORT_UCP needschar = TRUE; #endif } else if (*cc == XCL_RANGE) { cc += 2; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif cc++; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif #ifdef SUPPORT_UCP needschar = TRUE; #endif } #ifdef SUPPORT_UCP else { SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); cc++; switch(*cc) { case PT_ANY: break; case PT_LAMP: case PT_GC: case PT_PC: case PT_ALNUM: needstype = TRUE; break; case PT_SC: needsscript = TRUE; break; case PT_SPACE: case PT_PXSPACE: case PT_WORD: needstype = TRUE; needschar = TRUE; break; default: SLJIT_ASSERT_STOP(); break; } cc += 2; } #endif } #ifdef SUPPORT_UCP /* Simple register allocation. TMP1 is preferred if possible. */ if (needstype || needsscript) { if (needschar && !charsaved) OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); if (needschar) { if (needstype) { OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); typereg = RETURN_ADDR; } if (needsscript) scriptreg = TMP3; OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); } else if (needstype && needsscript) scriptreg = TMP3; /* In all other cases only one of them was specified, and that can goes to TMP1. */ if (needsscript) { if (scriptreg == TMP1) { OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3); } else { OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0); } } } #endif /* Generating code. */ cc = ccbegin; charoffset = 0; numberofcmps = 0; #ifdef SUPPORT_UCP typeoffset = 0; #endif while (*cc != XCL_END) { compares--; invertcmp = (compares == 0 && list != backtracks); jump = NULL; if (*cc == XCL_SINGLE) { cc ++; #ifdef SUPPORT_UTF if (common->utf) { GETCHARINC(c, cc); } else #endif c = *cc++; if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); numberofcmps++; } else if (numberofcmps > 0) { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); numberofcmps = 0; } else { jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); numberofcmps = 0; } } else if (*cc == XCL_RANGE) { cc ++; #ifdef SUPPORT_UTF if (common->utf) { GETCHARINC(c, cc); } else #endif c = *cc++; SET_CHAR_OFFSET(c); #ifdef SUPPORT_UTF if (common->utf) { GETCHARINC(c, cc); } else #endif c = *cc++; if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) { OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); numberofcmps++; } else if (numberofcmps > 0) { OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); numberofcmps = 0; } else { jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); numberofcmps = 0; } } #ifdef SUPPORT_UCP else { if (*cc == XCL_NOTPROP) invertcmp ^= 0x1; cc++; switch(*cc) { case PT_ANY: if (list != backtracks) { if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) continue; } else if (cc[-1] == XCL_NOTPROP) continue; jump = JUMP(SLJIT_JUMP); break; case PT_LAMP: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); break; case PT_GC: c = PRIV(ucp_typerange)[(int)cc[1] * 2]; SET_TYPE_OFFSET(c); jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); break; case PT_PC: jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); break; case PT_SC: jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); break; case PT_SPACE: case PT_PXSPACE: if (*cc == PT_SPACE) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset); } SET_CHAR_OFFSET(9); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); if (*cc == PT_SPACE) JUMPHERE(jump); SET_TYPE_OFFSET(ucp_Zl); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); break; case PT_WORD: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); /* ... fall through */ case PT_ALNUM: SET_TYPE_OFFSET(ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); SET_TYPE_OFFSET(ucp_Nd); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); break; } cc += 2; } #endif if (jump != NULL) add_jump(compiler, compares > 0 ? list : backtracks, jump); } if (found != NULL) set_jumps(found, LABEL()); } #undef SET_TYPE_OFFSET #undef SET_CHAR_OFFSET #endif static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) { DEFINE_COMPILER; int length; unsigned int c, oc, bit; compare_context context; struct sljit_jump *jump[4]; #ifdef SUPPORT_UTF struct sljit_label *label; #ifdef SUPPORT_UCP pcre_uchar propdata[5]; #endif #endif switch(type) { case OP_SOD: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); return cc; case OP_SOM: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); return cc; case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); return cc; case OP_NOT_DIGIT: case OP_DIGIT: detect_partial_match(common, backtracks); read_char8_type(common); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); return cc; case OP_NOT_WHITESPACE: case OP_WHITESPACE: detect_partial_match(common, backtracks); read_char8_type(common); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); return cc; case OP_NOT_WORDCHAR: case OP_WORDCHAR: detect_partial_match(common, backtracks); read_char8_type(common); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); return cc; case OP_ANY: detect_partial_match(common, backtracks); read_char(common); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); if (common->mode != JIT_PARTIAL_HARD_COMPILE) jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); else jump[1] = check_str_end(common); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); if (jump[1] != NULL) JUMPHERE(jump[1]); JUMPHERE(jump[0]); } else check_newlinechar(common, common->nltype, backtracks, TRUE); return cc; case OP_ALLANY: detect_partial_match(common, backtracks); #ifdef SUPPORT_UTF if (common->utf) { OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #ifdef COMPILE_PCRE8 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); #else /* COMPILE_PCRE8 */ #ifdef COMPILE_PCRE16 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ JUMPHERE(jump[0]); return cc; } #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); return cc; case OP_ANYBYTE: detect_partial_match(common, backtracks); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); return cc; #ifdef SUPPORT_UTF #ifdef SUPPORT_UCP case OP_NOTPROP: case OP_PROP: propdata[0] = 0; propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; propdata[2] = cc[0]; propdata[3] = cc[1]; propdata[4] = XCL_END; compile_xclass_trypath(common, propdata, backtracks); return cc + 2; #endif #endif case OP_ANYNL: detect_partial_match(common, backtracks); read_char(common); jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); /* We don't need to handle soft partial matching case. */ if (common->mode != JIT_PARTIAL_HARD_COMPILE) jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); else jump[1] = check_str_end(common); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); jump[3] = JUMP(SLJIT_JUMP); JUMPHERE(jump[0]); check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); JUMPHERE(jump[1]); JUMPHERE(jump[2]); JUMPHERE(jump[3]); return cc; case OP_NOT_HSPACE: case OP_HSPACE: detect_partial_match(common, backtracks); read_char(common); add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); return cc; case OP_NOT_VSPACE: case OP_VSPACE: detect_partial_match(common, backtracks); read_char(common); add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); return cc; #ifdef SUPPORT_UCP case OP_EXTUNI: detect_partial_match(common, backtracks); read_char(common); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc)); label = LABEL(); jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); read_char(common); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label); OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); JUMPHERE(jump[0]); if (common->mode == JIT_PARTIAL_HARD_COMPILE) { jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); /* Since we successfully read a char above, partial matching must occure. */ check_partial(common, TRUE); JUMPHERE(jump[0]); } return cc; #endif case OP_EODN: /* Requires rather complex checks. */ jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); if (common->mode == JIT_COMPILE) add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); else { jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL)); check_partial(common, TRUE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); JUMPHERE(jump[1]); } OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); } else if (common->nltype == NLTYPE_FIXED) { OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); } else { OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); jump[2] = JUMP(SLJIT_C_GREATER); add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS)); /* Equal. */ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); JUMPHERE(jump[1]); if (common->nltype == NLTYPE_ANYCRLF) { OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); } else { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0); read_char(common); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); } JUMPHERE(jump[2]); JUMPHERE(jump[3]); } JUMPHERE(jump[0]); check_partial(common, FALSE); return cc; case OP_EOD: add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); check_partial(common, FALSE); return cc; case OP_CIRC: OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); return cc; case OP_CIRCM: OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); jump[0] = JUMP(SLJIT_JUMP); JUMPHERE(jump[1]); add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); } else { skip_char_back(common); read_char(common); check_newlinechar(common, common->nltype, backtracks, FALSE); } JUMPHERE(jump[0]); return cc; case OP_DOLL: OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); if (!common->endonly) compile_char1_trypath(common, OP_EODN, cc, backtracks); else { add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); check_partial(common, FALSE); } return cc; case OP_DOLLM: jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); check_partial(common, FALSE); jump[0] = JUMP(SLJIT_JUMP); JUMPHERE(jump[1]); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); if (common->mode == JIT_COMPILE) add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); else { jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); /* STR_PTR = STR_END - IN_UCHARS(1) */ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); check_partial(common, TRUE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); JUMPHERE(jump[1]); } OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); } else { peek_char(common); check_newlinechar(common, common->nltype, backtracks, FALSE); } JUMPHERE(jump[0]); return cc; case OP_CHAR: case OP_CHARI: length = 1; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); #endif if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) { OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); context.length = IN_UCHARS(length); context.sourcereg = -1; #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED context.ucharptr = 0; #endif return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); } detect_partial_match(common, backtracks); read_char(common); #ifdef SUPPORT_UTF if (common->utf) { GETCHAR(c, cc); } else #endif c = *cc; if (type == OP_CHAR || !char_has_othercase(common, cc)) { add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); return cc + length; } oc = char_othercase(common, c); bit = c ^ oc; if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); return cc + length; } OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); return cc + length; case OP_NOT: case OP_NOTI: detect_partial_match(common, backtracks); length = 1; #ifdef SUPPORT_UTF if (common->utf) { #ifdef COMPILE_PCRE8 c = *cc; if (c < 128) { OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); if (type == OP_NOT || !char_has_othercase(common, cc)) add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); else { /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); } /* Skip the variable-length character. */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(jump[0]); return cc + 1; } else #endif /* COMPILE_PCRE8 */ { GETCHARLEN(c, cc, length); read_char(common); } } else #endif /* SUPPORT_UTF */ { read_char(common); c = *cc; } if (type == OP_NOT || !char_has_othercase(common, cc)) add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); else { oc = char_othercase(common, c); bit = c ^ oc; if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); } else { add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); } } return cc + length; case OP_CLASS: case OP_NCLASS: detect_partial_match(common, backtracks); read_char(common); #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 jump[0] = NULL; #ifdef COMPILE_PCRE8 /* This check only affects 8 bit mode. In other modes, we always need to compare the value with 255. */ if (common->utf) #endif /* COMPILE_PCRE8 */ { jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); if (type == OP_CLASS) { add_jump(compiler, backtracks, jump[0]); jump[0] = NULL; } } #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 if (jump[0] != NULL) JUMPHERE(jump[0]); #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ return cc + 32 / sizeof(pcre_uchar); #if defined SUPPORT_UTF || defined COMPILE_PCRE16 case OP_XCLASS: compile_xclass_trypath(common, cc + LINK_SIZE, backtracks); return cc + GET(cc, 0) - 1; #endif case OP_REVERSE: length = GET(cc, 0); if (length == 0) return cc + LINK_SIZE; OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); #ifdef SUPPORT_UTF if (common->utf) { OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); label = LABEL(); add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); skip_char_back(common); OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, label); } else #endif { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); } check_start_used_ptr(common); return cc + LINK_SIZE; } SLJIT_ASSERT_STOP(); return cc; } static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks) { /* This function consumes at least one input character. */ /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ DEFINE_COMPILER; pcre_uchar *ccbegin = cc; compare_context context; int size; context.length = 0; do { if (cc >= ccend) break; if (*cc == OP_CHAR) { size = 1; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(cc[1])) size += GET_EXTRALEN(cc[1]); #endif } else if (*cc == OP_CHARI) { size = 1; #ifdef SUPPORT_UTF if (common->utf) { if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) size = 0; else if (HAS_EXTRALEN(cc[1])) size += GET_EXTRALEN(cc[1]); } else #endif if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) size = 0; } else size = 0; cc += 1 + size; context.length += IN_UCHARS(size); } while (size > 0 && context.length <= 128); cc = ccbegin; if (context.length > 0) { /* We have a fixed-length byte sequence. */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); context.sourcereg = -1; #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED context.ucharptr = 0; #endif do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); return cc; } /* A non-fixed length character will be checked if length == 0. */ return compile_char1_trypath(common, *cc, cc + 1, backtracks); } static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) { DEFINE_COMPILER; int offset = GET2(cc, 1) << 1; OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); if (!common->jscript_compat) { if (backtracks == NULL) { /* OVECTOR(1) contains the "string begin - 1" constant. */ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); return JUMP(SLJIT_C_NOT_ZERO); } add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); } return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); } /* Forward definitions. */ static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); static void compile_backtrackpath(compiler_common *, struct backtrack_common *); #define PUSH_BACKTRACK(size, ccstart, error) \ do \ { \ backtrack = sljit_alloc_memory(compiler, (size)); \ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ return error; \ memset(backtrack, 0, size); \ backtrack->prev = parent->top; \ backtrack->cc = (ccstart); \ parent->top = backtrack; \ } \ while (0) #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \ do \ { \ backtrack = sljit_alloc_memory(compiler, (size)); \ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ return; \ memset(backtrack, 0, size); \ backtrack->prev = parent->top; \ backtrack->cc = (ccstart); \ parent->top = backtrack; \ } \ while (0) #define BACKTRACK_AS(type) ((type *)backtrack) static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) { DEFINE_COMPILER; int offset = GET2(cc, 1) << 1; struct sljit_jump *jump = NULL; struct sljit_jump *partial; struct sljit_jump *nopartial; OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); /* OVECTOR(1) contains the "string begin - 1" constant. */ if (withchecks && !common->jscript_compat) add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); #if defined SUPPORT_UTF && defined SUPPORT_UCP if (common->utf && *cc == OP_REFI) { SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); if (withchecks) jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); /* Needed to save important temporary registers. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); if (common->mode == JIT_COMPILE) add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); else { add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); check_partial(common, FALSE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); JUMPHERE(nopartial); } OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); } else #endif /* SUPPORT_UTF && SUPPORT_UCP */ { OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); if (withchecks) jump = JUMP(SLJIT_C_ZERO); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); if (common->mode == JIT_COMPILE) add_jump(compiler, backtracks, partial); add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); if (common->mode != JIT_COMPILE) { nopartial = JUMP(SLJIT_JUMP); JUMPHERE(partial); /* TMP2 -= STR_END - STR_PTR */ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); JUMPHERE(partial); check_partial(common, FALSE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); JUMPHERE(nopartial); } } if (jump != NULL) { if (emptyfail) add_jump(compiler, backtracks, jump); else JUMPHERE(jump); } return cc + 1 + IMM2_SIZE; } static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar type; struct sljit_label *label; struct sljit_jump *zerolength; struct sljit_jump *jump = NULL; pcre_uchar *ccbegin = cc; int min = 0, max = 0; BOOL minimize; PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); type = cc[1 + IMM2_SIZE]; minimize = (type & 0x1) != 0; switch(type) { case OP_CRSTAR: case OP_CRMINSTAR: min = 0; max = 0; cc += 1 + IMM2_SIZE + 1; break; case OP_CRPLUS: case OP_CRMINPLUS: min = 1; max = 0; cc += 1 + IMM2_SIZE + 1; break; case OP_CRQUERY: case OP_CRMINQUERY: min = 0; max = 1; cc += 1 + IMM2_SIZE + 1; break; case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(cc, 1 + IMM2_SIZE + 1); max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE); cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE; break; default: SLJIT_ASSERT_STOP(); break; } if (!minimize) { if (min == 0) { allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); /* Temporary release of STR_PTR. */ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); zerolength = compile_ref_checks(common, ccbegin, NULL); /* Restore if not zero length. */ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); } else { allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); } if (min > 1 || max > 1) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); label = LABEL(); compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); if (min > 1 || max > 1) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); if (min > 1) CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); if (max > 1) { jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); JUMPTO(SLJIT_JUMP, label); JUMPHERE(jump); } } if (max == 0) { /* Includes min > 1 case as well. */ allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); JUMPTO(SLJIT_JUMP, label); } JUMPHERE(zerolength); BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); decrease_call_count(common); return cc; } allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); if (type != OP_CRMINSTAR) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); if (min == 0) { zerolength = compile_ref_checks(common, ccbegin, NULL); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); jump = JUMP(SLJIT_JUMP); } else zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); if (max > 0) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (min > 1) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath); } else if (max > 0) OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); if (jump != NULL) JUMPHERE(jump); JUMPHERE(zerolength); decrease_call_count(common); return cc; } static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; recurse_entry *entry = common->entries; recurse_entry *prev = NULL; int start = GET(cc, 1); PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); while (entry != NULL) { if (entry->start == start) break; prev = entry; entry = entry->next; } if (entry == NULL) { entry = sljit_alloc_memory(compiler, sizeof(recurse_entry)); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; entry->next = NULL; entry->entry = NULL; entry->calls = NULL; entry->start = start; if (prev != NULL) prev->next = entry; else common->entries = entry; } if (common->has_set_som && common->mark_ptr != 0) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); allocate_stack(common, 2); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); } else if (common->has_set_som || common->mark_ptr != 0) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); } if (entry->entry == NULL) add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); else JUMPTO(SLJIT_FAST_CALL, entry->entry); /* Leave if the match is failed. */ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); return cc + 1 + LINK_SIZE; } static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) { DEFINE_COMPILER; int framesize; int localptr; backtrack_common altbacktrack; pcre_uchar *ccbegin; pcre_uchar opcode; pcre_uchar bra = OP_BRA; jump_list *tmp = NULL; jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; jump_list **found; /* Saving previous accept variables. */ struct sljit_label *save_leavelabel = common->leavelabel; struct sljit_label *save_acceptlabel = common->acceptlabel; jump_list *save_leave = common->leave; jump_list *save_accept = common->accept; struct sljit_jump *jump; struct sljit_jump *brajump = NULL; if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) { SLJIT_ASSERT(!conditional); bra = *cc; cc++; } localptr = PRIV_DATA(cc); SLJIT_ASSERT(localptr != 0); framesize = get_framesize(common, cc, FALSE); backtrack->framesize = framesize; backtrack->localptr = localptr; opcode = *cc; SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; ccbegin = cc; cc += GET(cc, 1); if (bra == OP_BRAMINZERO) { /* This is a braminzero backtrack path. */ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); } if (framesize < 0) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } else { allocate_stack(common, framesize + 2); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); init_frame(common, ccbegin, framesize + 1, 2, FALSE); } memset(&altbacktrack, 0, sizeof(backtrack_common)); common->leavelabel = NULL; common->leave = NULL; while (1) { common->acceptlabel = NULL; common->accept = NULL; altbacktrack.top = NULL; altbacktrack.topbacktracks = NULL; if (*ccbegin == OP_ALT) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); altbacktrack.cc = ccbegin; compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { common->leavelabel = save_leavelabel; common->acceptlabel = save_acceptlabel; common->leave = save_leave; common->accept = save_accept; return NULL; } common->acceptlabel = LABEL(); if (common->accept != NULL) set_jumps(common->accept, common->acceptlabel); /* Reset stack. */ if (framesize < 0) OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); else { if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) { /* We don't need to keep the STR_PTR, only the previous localptr. */ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); } else { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); } } if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) { /* We know that STR_PTR was stored on the top of the stack. */ if (conditional) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); else if (bra == OP_BRAZERO) { if (framesize < 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); else { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else if (framesize >= 0) { /* For OP_BRA and OP_BRAMINZERO. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); } } add_jump(compiler, found, JUMP(SLJIT_JUMP)); compile_backtrackpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { common->leavelabel = save_leavelabel; common->acceptlabel = save_acceptlabel; common->leave = save_leave; common->accept = save_accept; return NULL; } set_jumps(altbacktrack.topbacktracks, LABEL()); if (*cc != OP_ALT) break; ccbegin = cc; cc += GET(cc, 1); } /* None of them matched. */ if (common->leave != NULL) set_jumps(common->leave, LABEL()); if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { /* Assert is failed. */ if (conditional || bra == OP_BRAZERO) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (framesize < 0) { /* The topmost item should be 0. */ if (bra == OP_BRAZERO) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); else free_stack(common, 1); } else { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); /* The topmost item should be 0. */ if (bra == OP_BRAZERO) { free_stack(common, framesize + 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else free_stack(common, framesize + 2); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } jump = JUMP(SLJIT_JUMP); if (bra != OP_BRAZERO) add_jump(compiler, target, jump); /* Assert is successful. */ set_jumps(tmp, LABEL()); if (framesize < 0) { /* We know that STR_PTR was stored on the top of the stack. */ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); /* Keep the STR_PTR on the top of the stack. */ if (bra == OP_BRAZERO) OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); else if (bra == OP_BRAMINZERO) { OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } } else { if (bra == OP_BRA) { /* We don't need to keep the STR_PTR, only the previous localptr. */ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); } else { /* We don't need to keep the STR_PTR, only the previous localptr. */ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); } } if (bra == OP_BRAZERO) { backtrack->trypath = LABEL(); sljit_set_label(jump, backtrack->trypath); } else if (bra == OP_BRAMINZERO) { JUMPTO(SLJIT_JUMP, backtrack->trypath); JUMPHERE(brajump); if (framesize >= 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); } set_jumps(backtrack->common.topbacktracks, LABEL()); } } else { /* AssertNot is successful. */ if (framesize < 0) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (bra != OP_BRA) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); else free_stack(common, 1); } else { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); /* The topmost item should be 0. */ if (bra != OP_BRA) { free_stack(common, framesize + 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else free_stack(common, framesize + 2); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } if (bra == OP_BRAZERO) backtrack->trypath = LABEL(); else if (bra == OP_BRAMINZERO) { JUMPTO(SLJIT_JUMP, backtrack->trypath); JUMPHERE(brajump); } if (bra != OP_BRA) { SLJIT_ASSERT(found == &backtrack->common.topbacktracks); set_jumps(backtrack->common.topbacktracks, LABEL()); backtrack->common.topbacktracks = NULL; } } common->leavelabel = save_leavelabel; common->acceptlabel = save_acceptlabel; common->leave = save_leave; common->accept = save_accept; return cc + 1 + LINK_SIZE; } static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table) { int condition = FALSE; pcre_uchar *slotA = name_table; pcre_uchar *slotB; sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; sljit_w no_capture; int i; locals += refno & 0xff; refno >>= 8; no_capture = locals[1]; for (i = 0; i < name_count; i++) { if (GET2(slotA, 0) == refno) break; slotA += name_entry_size; } if (i < name_count) { /* Found a name for the number - there can be only one; duplicate names for different numbers are allowed, but not vice versa. First scan down for duplicates. */ slotB = slotA; while (slotB > name_table) { slotB -= name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = locals[GET2(slotB, 0) << 1] != no_capture; if (condition) break; } else break; } /* Scan up for duplicates */ if (!condition) { slotB = slotA; for (i++; i < name_count; i++) { slotB += name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = locals[GET2(slotB, 0) << 1] != no_capture; if (condition) break; } else break; } } } return condition; } static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table) { int condition = FALSE; pcre_uchar *slotA = name_table; pcre_uchar *slotB; sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)]; int i; for (i = 0; i < name_count; i++) { if (GET2(slotA, 0) == recno) break; slotA += name_entry_size; } if (i < name_count) { /* Found a name for the number - there can be only one; duplicate names for different numbers are allowed, but not vice versa. First scan down for duplicates. */ slotB = slotA; while (slotB > name_table) { slotB -= name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == group_num; if (condition) break; } else break; } /* Scan up for duplicates */ if (!condition) { slotB = slotA; for (i++; i < name_count; i++) { slotB += name_entry_size; if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == group_num; if (condition) break; } else break; } } } return condition; } /* Handling bracketed expressions is probably the most complex part. Stack layout naming characters: S - Push the current STR_PTR 0 - Push a 0 (NULL) A - Push the current STR_PTR. Needed for restoring the STR_PTR before the next alternative. Not pushed if there are no alternatives. M - Any values pushed by the current alternative. Can be empty, or anything. C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. L - Push the previous local (pointed by localptr) to the stack () - opional values stored on the stack ()* - optonal, can be stored multiple times The following list shows the regular expression templates, their PCRE byte codes and stack layout supported by pcre-sljit. (?:) OP_BRA | OP_KET A M () OP_CBRA | OP_KET C M (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )* OP_SBRA | OP_KETRMAX 0 L M S ( L M S )* (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )* OP_SBRA | OP_KETRMIN 0 L M S ( L M S )* ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )* OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )* ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )* OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )* (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 ) (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 ) ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 ) ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 ) (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )* OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )* (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )* OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )* ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )* OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )* ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )* OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )* Stack layout naming characters: A - Push the alternative index (starting from 0) on the stack. Not pushed if there is no alternatives. M - Any values pushed by the current alternative. Can be empty, or anything. The next list shows the possible content of a bracket: (|) OP_*BRA | OP_ALT ... M A (?()|) OP_*COND | OP_ALT M A (?>|) OP_ONCE | OP_ALT ... [stack trace] M A (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A Or nothing, if trace is unnecessary */ static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar opcode; int localptr = 0; int offset = 0; int stacksize; pcre_uchar *ccbegin; pcre_uchar *trypath; pcre_uchar bra = OP_BRA; pcre_uchar ket; assert_backtrack *assert; BOOL has_alternatives; struct sljit_jump *jump; struct sljit_jump *skip; struct sljit_label *rmaxlabel = NULL; struct sljit_jump *braminzerojump = NULL; PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) { bra = *cc; cc++; opcode = *cc; } opcode = *cc; ccbegin = cc; trypath = ccbegin + 1 + LINK_SIZE; if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) { /* Drop this bracket_backtrack. */ parent->top = backtrack->prev; return bracketend(cc); } ket = *(bracketend(cc) - 1 - LINK_SIZE); SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); cc += GET(cc, 1); has_alternatives = *cc == OP_ALT; if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE; if (*trypath == OP_NRREF) { stacksize = GET2(trypath, 1); if (common->currententry == NULL || stacksize == RREF_ANY) has_alternatives = FALSE; else if (common->currententry->start == 0) has_alternatives = stacksize != 0; else has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE); } } if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) opcode = OP_SCOND; if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) opcode = OP_ONCE; if (opcode == OP_CBRA || opcode == OP_SCBRA) { /* Capturing brackets has a pre-allocated space. */ offset = GET2(ccbegin, 1 + LINK_SIZE); localptr = OVECTOR_PRIV(offset); offset <<= 1; BACKTRACK_AS(bracket_backtrack)->localptr = localptr; trypath += IMM2_SIZE; } else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) { /* Other brackets simply allocate the next entry. */ localptr = PRIV_DATA(ccbegin); SLJIT_ASSERT(localptr != 0); BACKTRACK_AS(bracket_backtrack)->localptr = localptr; if (opcode == OP_ONCE) BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE); } /* Instructions before the first alternative. */ stacksize = 0; if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) stacksize++; if (bra == OP_BRAZERO) stacksize++; if (stacksize > 0) allocate_stack(common, stacksize); stacksize = 0; if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); stacksize++; } if (bra == OP_BRAZERO) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); if (bra == OP_BRAMINZERO) { /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (ket != OP_KETRMIN) { free_stack(common, 1); braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); } else { if (opcode == OP_ONCE || opcode >= OP_SBRA) { jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); /* Nothing stored during the first run. */ skip = JUMP(SLJIT_JUMP); JUMPHERE(jump); /* Checking zero-length iteration. */ if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { /* When we come from outside, localptr contains the previous STR_PTR. */ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); } else { /* Except when the whole stack frame must be saved. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w)); } JUMPHERE(skip); } else { jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); JUMPHERE(jump); } } } if (ket == OP_KETRMIN) BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); if (ket == OP_KETRMAX) { rmaxlabel = LABEL(); if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel; } /* Handling capturing brackets and alternatives. */ if (opcode == OP_ONCE) { if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { /* Neither capturing brackets nor recursions are not found in the block. */ if (ket == OP_KETRMIN) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); } else if (ket == OP_KETRMAX || has_alternatives) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } else OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); } else { if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) { allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE); } else { allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE); } } } else if (opcode == OP_CBRA || opcode == OP_SCBRA) { /* Saving the previous values. */ allocate_stack(common, 3); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); } else if (opcode == OP_SBRA || opcode == OP_SCOND) { /* Saving the previous value. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); } else if (has_alternatives) { /* Pushing the starting string pointer. */ allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } /* Generating code for the first alternative. */ if (opcode == OP_COND || opcode == OP_SCOND) { if (*trypath == OP_CREF) { SLJIT_ASSERT(has_alternatives); add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); trypath += 1 + IMM2_SIZE; } else if (*trypath == OP_NCREF) { SLJIT_ASSERT(has_alternatives); stacksize = GET2(trypath, 1); jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w))); GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); JUMPHERE(jump); trypath += 1 + IMM2_SIZE; } else if (*trypath == OP_RREF || *trypath == OP_NRREF) { /* Never has other case. */ BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; stacksize = GET2(trypath, 1); if (common->currententry == NULL) stacksize = 0; else if (stacksize == RREF_ANY) stacksize = 1; else if (common->currententry->start == 0) stacksize = stacksize == 0; else stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE); if (*trypath == OP_RREF || stacksize || common->currententry == NULL) { SLJIT_ASSERT(!has_alternatives); if (stacksize != 0) trypath += 1 + IMM2_SIZE; else { if (*cc == OP_ALT) { trypath = cc + 1 + LINK_SIZE; cc += GET(cc, 1); } else trypath = cc; } } else { SLJIT_ASSERT(has_alternatives); stacksize = GET2(trypath, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); trypath += 1 + IMM2_SIZE; } } else { SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT); /* Similar code as PUSH_BACKTRACK macro. */ assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; memset(assert, 0, sizeof(assert_backtrack)); assert->common.cc = trypath; BACKTRACK_AS(bracket_backtrack)->u.assert = assert; trypath = compile_assert_trypath(common, trypath, assert, TRUE); } } compile_trypath(common, trypath, cc, backtrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; if (opcode == OP_ONCE) { if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); /* TMP2 which is set here used by OP_KETRMAX below. */ if (ket == OP_KETRMAX) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); else if (ket == OP_KETRMIN) { /* Move the STR_PTR to the localptr. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); } } else { stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w)); if (ket == OP_KETRMAX) { /* TMP2 which is set here used by OP_KETRMAX below. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } } } stacksize = 0; if (ket != OP_KET || bra != OP_BRA) stacksize++; if (has_alternatives && opcode != OP_ONCE) stacksize++; if (stacksize > 0) allocate_stack(common, stacksize); stacksize = 0; if (ket != OP_KET) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); stacksize++; } else if (bra != OP_BRA) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); stacksize++; } if (has_alternatives) { if (opcode != OP_ONCE) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); if (ket != OP_KETRMAX) BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); } /* Must be after the trypath label. */ if (offset != 0) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); } if (ket == OP_KETRMAX) { if (opcode == OP_ONCE || opcode >= OP_SBRA) { if (has_alternatives) BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); /* Checking zero-length iteration. */ if (opcode != OP_ONCE) { CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel); /* Drop STR_PTR for greedy plus quantifier. */ if (bra != OP_BRAZERO) free_stack(common, 1); } else /* TMP2 must contain the starting STR_PTR. */ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel); } else JUMPTO(SLJIT_JUMP, rmaxlabel); BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); } if (bra == OP_BRAZERO) BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL(); if (bra == OP_BRAMINZERO) { /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath); if (braminzerojump != NULL) { JUMPHERE(braminzerojump); /* We need to release the end pointer to perform the backtrack for the zero-length iteration. When framesize is < 0, OP_ONCE will do the release itself. */ if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); } else if (ket == OP_KETRMIN && opcode != OP_ONCE) free_stack(common, 1); } /* Continue to the normal backtrack. */ } if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) decrease_call_count(common); /* Skip the other alternatives. */ while (*cc == OP_ALT) cc += GET(cc, 1); cc += 1 + LINK_SIZE; return cc; } static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar opcode; int localptr; int cbraprivptr = 0; int framesize; int stacksize; int offset = 0; BOOL zero = FALSE; pcre_uchar *ccbegin = NULL; int stack; struct sljit_label *loop = NULL; struct jump_list *emptymatch = NULL; PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL); if (*cc == OP_BRAPOSZERO) { zero = TRUE; cc++; } opcode = *cc; localptr = PRIV_DATA(cc); SLJIT_ASSERT(localptr != 0); BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr; switch(opcode) { case OP_BRAPOS: case OP_SBRAPOS: ccbegin = cc + 1 + LINK_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: offset = GET2(cc, 1 + LINK_SIZE); cbraprivptr = OVECTOR_PRIV(offset); offset <<= 1; ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE; break; default: SLJIT_ASSERT_STOP(); break; } framesize = get_framesize(common, cc, FALSE); BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; if (framesize < 0) { stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; if (!zero) stacksize++; BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; allocate_stack(common, stacksize); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); } else OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (!zero) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1); } else { stacksize = framesize + 1; if (!zero) stacksize++; if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) stacksize++; BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; allocate_stack(common, stacksize); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); stack = 0; if (!zero) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); stack++; } if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); stack++; } OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE); } if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); loop = LABEL(); while (*cc != OP_KETRPOS) { backtrack->top = NULL; backtrack->topbacktracks = NULL; cc += GET(cc, 1); compile_trypath(common, ccbegin, cc, backtrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; if (framesize < 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); } else { if (opcode == OP_SBRAPOS) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); if (!zero) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); } else { if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) { OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); } else { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w)); if (opcode == OP_SBRAPOS) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0); } if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); if (!zero) { if (framesize < 0) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); else OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } } JUMPTO(SLJIT_JUMP, loop); flush_stubs(common); compile_backtrackpath(common, backtrack->top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; set_jumps(backtrack->topbacktracks, LABEL()); if (framesize < 0) { if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); else OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } else { if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) { /* Last alternative. */ if (*cc == OP_KETRPOS) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); } else { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); } } if (*cc == OP_KETRPOS) break; ccbegin = cc + 1 + LINK_SIZE; } backtrack->topbacktracks = NULL; if (!zero) { if (framesize < 0) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); else /* TMP2 is set to [localptr] above. */ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0)); } /* None of them matched. */ set_jumps(emptymatch, LABEL()); decrease_call_count(common); return cc + 1 + LINK_SIZE; } static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end) { int class_len; *opcode = *cc; if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) { cc++; *type = OP_CHAR; } else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI) { cc++; *type = OP_CHARI; *opcode -= OP_STARI - OP_STAR; } else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO) { cc++; *type = OP_NOT; *opcode -= OP_NOTSTAR - OP_STAR; } else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI) { cc++; *type = OP_NOTI; *opcode -= OP_NOTSTARI - OP_STAR; } else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) { cc++; *opcode -= OP_TYPESTAR - OP_STAR; *type = 0; } else { SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS); *type = *opcode; cc++; class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); *opcode = cc[class_len - 1]; if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) { *opcode -= OP_CRSTAR - OP_STAR; if (end != NULL) *end = cc + class_len; } else { SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE); *arg1 = GET2(cc, (class_len + IMM2_SIZE)); *arg2 = GET2(cc, class_len); if (*arg2 == 0) { SLJIT_ASSERT(*arg1 != 0); *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO; } if (*arg1 == *arg2) *opcode = OP_EXACT; if (end != NULL) *end = cc + class_len + 2 * IMM2_SIZE; } return cc; } if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO) { *arg1 = GET2(cc, 0); cc += IMM2_SIZE; } if (*type == 0) { *type = *cc; if (end != NULL) *end = next_opcode(common, cc); cc++; return cc; } if (end != NULL) { *end = cc + 1; #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); #endif } return cc; } static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar opcode; pcre_uchar type; int arg1 = -1, arg2 = -1; pcre_uchar* end; jump_list *nomatch = NULL; struct sljit_jump *jump = NULL; struct sljit_label *label; PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); switch(opcode) { case OP_STAR: case OP_PLUS: case OP_UPTO: case OP_CRRANGE: if (type == OP_ANYNL || type == OP_EXTUNI) { if (opcode == OP_STAR || opcode == OP_UPTO) { allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); } else { allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } if (opcode == OP_UPTO || opcode == OP_CRRANGE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); label = LABEL(); compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); if (opcode == OP_UPTO || opcode == OP_CRRANGE) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); if (opcode == OP_CRRANGE && arg2 > 0) CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label); if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0)) jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); } allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); JUMPTO(SLJIT_JUMP, label); if (jump != NULL) JUMPHERE(jump); } else { if (opcode == OP_PLUS) compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); label = LABEL(); compile_char1_trypath(common, type, cc, &nomatch); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0)) { OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); JUMPTO(SLJIT_JUMP, label); } else { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); } set_jumps(nomatch, LABEL()); if (opcode == OP_CRRANGE) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_MINSTAR: case OP_MINPLUS: if (opcode == OP_MINPLUS) compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_MINUPTO: case OP_CRMINRANGE: allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); if (opcode == OP_CRMINRANGE) add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_QUERY: case OP_MINQUERY: allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (opcode == OP_QUERY) compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_EXACT: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); label = LABEL(); compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); break; case OP_POSSTAR: case OP_POSPLUS: case OP_POSUPTO: if (opcode != OP_POSSTAR) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); label = LABEL(); compile_char1_trypath(common, type, cc, &nomatch); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); if (opcode != OP_POSUPTO) { if (opcode == OP_POSPLUS) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2); JUMPTO(SLJIT_JUMP, label); } else { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); } set_jumps(nomatch, LABEL()); if (opcode == OP_POSPLUS) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); break; case OP_POSQUERY: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); compile_char1_trypath(common, type, cc, &nomatch); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); set_jumps(nomatch, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); break; default: SLJIT_ASSERT_STOP(); break; } decrease_call_count(common); return end; } static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); if (*cc == OP_FAIL) { add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); return cc + 1; } if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL) { /* No need to check notempty conditions. */ if (common->acceptlabel == NULL) add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); else JUMPTO(SLJIT_JUMP, common->acceptlabel); return cc + 1; } if (common->acceptlabel == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0))); else CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); if (common->acceptlabel == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); else CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); if (common->acceptlabel == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); else CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel); add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); return cc + 1; } static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc) { DEFINE_COMPILER; int offset = GET2(cc, 1); /* Data will be discarded anyway... */ if (common->currententry != NULL) return cc + 1 + IMM2_SIZE; OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); offset <<= 1; OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); return cc + 1 + IMM2_SIZE; } static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; while (cc < ccend) { switch(*cc) { case OP_SOD: case OP_SOM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: case OP_ALLANY: case OP_ANYBYTE: case OP_NOTPROP: case OP_PROP: case OP_ANYNL: case OP_NOT_HSPACE: case OP_HSPACE: case OP_NOT_VSPACE: case OP_VSPACE: case OP_EXTUNI: case OP_EODN: case OP_EOD: case OP_CIRC: case OP_CIRCM: case OP_DOLL: case OP_DOLLM: case OP_NOT: case OP_NOTI: case OP_REVERSE: cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; case OP_SET_SOM: PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); cc++; break; case OP_CHAR: case OP_CHARI: if (common->mode == JIT_COMPILE) cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); else cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: case OP_UPTO: case OP_MINUPTO: case OP_EXACT: case OP_POSSTAR: case OP_POSPLUS: case OP_POSQUERY: case OP_POSUPTO: case OP_STARI: case OP_MINSTARI: case OP_PLUSI: case OP_MINPLUSI: case OP_QUERYI: case OP_MINQUERYI: case OP_UPTOI: case OP_MINUPTOI: case OP_EXACTI: case OP_POSSTARI: case OP_POSPLUSI: case OP_POSQUERYI: case OP_POSUPTOI: case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTEXACT: case OP_NOTPOSSTAR: case OP_NOTPOSPLUS: case OP_NOTPOSQUERY: case OP_NOTPOSUPTO: case OP_NOTSTARI: case OP_NOTMINSTARI: case OP_NOTPLUSI: case OP_NOTMINPLUSI: case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTUPTOI: case OP_NOTMINUPTOI: case OP_NOTEXACTI: case OP_NOTPOSSTARI: case OP_NOTPOSPLUSI: case OP_NOTPOSQUERYI: case OP_NOTPOSUPTOI: case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSUPTO: cc = compile_iterator_trypath(common, cc, parent); break; case OP_CLASS: case OP_NCLASS: if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE) cc = compile_iterator_trypath(common, cc, parent); else cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; #if defined SUPPORT_UTF || defined COMPILE_PCRE16 case OP_XCLASS: if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) cc = compile_iterator_trypath(common, cc, parent); else cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; #endif case OP_REF: case OP_REFI: if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE) cc = compile_ref_iterator_trypath(common, cc, parent); else cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); break; case OP_RECURSE: cc = compile_recurse_trypath(common, cc, parent); break; case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); break; case OP_BRAMINZERO: PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc); cc = bracketend(cc + 1); if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) { allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } else { allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); } BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL(); if (cc[1] > OP_ASSERTBACK_NOT) decrease_call_count(common); break; case OP_ONCE: case OP_ONCE_NC: case OP_BRA: case OP_CBRA: case OP_COND: case OP_SBRA: case OP_SCBRA: case OP_SCOND: cc = compile_bracket_trypath(common, cc, parent); break; case OP_BRAZERO: if (cc[1] > OP_ASSERTBACK_NOT) cc = compile_bracket_trypath(common, cc, parent); else { PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); } break; case OP_BRAPOS: case OP_CBRAPOS: case OP_SBRAPOS: case OP_SCBRAPOS: case OP_BRAPOSZERO: cc = compile_bracketpos_trypath(common, cc, parent); break; case OP_MARK: PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); SLJIT_ASSERT(common->mark_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); allocate_stack(common, 1); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); cc += 1 + 2 + cc[1]; break; case OP_COMMIT: PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); cc += 1; break; case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: cc = compile_fail_accept_trypath(common, cc, parent); break; case OP_CLOSE: cc = compile_close_trypath(common, cc); break; case OP_SKIPZERO: cc = bracketend(cc + 1); break; default: SLJIT_ASSERT_STOP(); return; } if (cc == NULL) return; } SLJIT_ASSERT(cc == ccend); } #undef PUSH_BACKTRACK #undef PUSH_BACKTRACK_NOVALUE #undef BACKTRACK_AS #define COMPILE_BACKTRACKPATH(current) \ do \ { \ compile_backtrackpath(common, (current)); \ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ return; \ } \ while (0) #define CURRENT_AS(type) ((type *)current) static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; pcre_uchar *cc = current->cc; pcre_uchar opcode; pcre_uchar type; int arg1 = -1, arg2 = -1; struct sljit_label *label = NULL; struct sljit_jump *jump = NULL; jump_list *jumplist = NULL; cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL); switch(opcode) { case OP_STAR: case OP_PLUS: case OP_UPTO: case OP_CRRANGE: if (type == OP_ANYNL || type == OP_EXTUNI) { set_jumps(current->topbacktracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); } else { if (opcode <= OP_PLUS || opcode == OP_UPTO) arg2 = 0; OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1); OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); skip_char_back(common); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); if (opcode == OP_CRRANGE) set_jumps(current->topbacktracks, LABEL()); JUMPHERE(jump); free_stack(common, 2); if (opcode == OP_PLUS) set_jumps(current->topbacktracks, LABEL()); } break; case OP_MINSTAR: case OP_MINPLUS: OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); compile_char1_trypath(common, type, cc, &jumplist); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(jumplist, LABEL()); free_stack(common, 1); if (opcode == OP_MINPLUS) set_jumps(current->topbacktracks, LABEL()); break; case OP_MINUPTO: case OP_CRMINRANGE: if (opcode == OP_CRMINRANGE) { label = LABEL(); set_jumps(current->topbacktracks, label); } OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); compile_char1_trypath(common, type, cc, &jumplist); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); if (opcode == OP_CRMINRANGE) CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); if (opcode == OP_CRMINRANGE && arg1 == 0) JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); else CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(jumplist, LABEL()); free_stack(common, 2); break; case OP_QUERY: OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); jump = JUMP(SLJIT_JUMP); set_jumps(current->topbacktracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); JUMPHERE(jump); free_stack(common, 1); break; case OP_MINQUERY: OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); compile_char1_trypath(common, type, cc, &jumplist); JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(jumplist, LABEL()); JUMPHERE(jump); free_stack(common, 1); break; case OP_EXACT: case OP_POSPLUS: set_jumps(current->topbacktracks, LABEL()); break; case OP_POSSTAR: case OP_POSQUERY: case OP_POSUPTO: break; default: SLJIT_ASSERT_STOP(); break; } } static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; pcre_uchar *cc = current->cc; pcre_uchar type; type = cc[1 + IMM2_SIZE]; if ((type & 0x1) == 0) { set_jumps(current->topbacktracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); return; } OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(current->topbacktracks, LABEL()); free_stack(common, 2); } static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; set_jumps(current->topbacktracks, LABEL()); if (common->has_set_som && common->mark_ptr != 0) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); free_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); } else if (common->has_set_som || common->mark_ptr != 0) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); } } static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; pcre_uchar *cc = current->cc; pcre_uchar bra = OP_BRA; struct sljit_jump *brajump = NULL; SLJIT_ASSERT(*cc != OP_BRAMINZERO); if (*cc == OP_BRAZERO) { bra = *cc; cc++; } if (bra == OP_BRAZERO) { SLJIT_ASSERT(current->topbacktracks == NULL); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } if (CURRENT_AS(assert_backtrack)->framesize < 0) { set_jumps(current->topbacktracks, LABEL()); if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); free_stack(common, 1); } return; } if (bra == OP_BRAZERO) { if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); free_stack(common, 1); return; } free_stack(common, 1); brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); } if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w)); set_jumps(current->topbacktracks, LABEL()); } else set_jumps(current->topbacktracks, LABEL()); if (bra == OP_BRAZERO) { /* We know there is enough place on the stack. */ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath); JUMPHERE(brajump); } } static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; int opcode; int offset = 0; int localptr = CURRENT_AS(bracket_backtrack)->localptr; int stacksize; int count; pcre_uchar *cc = current->cc; pcre_uchar *ccbegin; pcre_uchar *ccprev; jump_list *jumplist = NULL; jump_list *jumplistitem = NULL; pcre_uchar bra = OP_BRA; pcre_uchar ket; assert_backtrack *assert; BOOL has_alternatives; struct sljit_jump *brazero = NULL; struct sljit_jump *once = NULL; struct sljit_jump *cond = NULL; struct sljit_label *rminlabel = NULL; if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) { bra = *cc; cc++; } opcode = *cc; ccbegin = cc; ket = *(bracketend(ccbegin) - 1 - LINK_SIZE); cc += GET(cc, 1); has_alternatives = *cc == OP_ALT; if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; if (opcode == OP_CBRA || opcode == OP_SCBRA) offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) opcode = OP_SCOND; if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) opcode = OP_ONCE; if (ket == OP_KETRMAX) { if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0); } } else if (ket == OP_KETRMIN) { if (bra != OP_BRAMINZERO) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (opcode >= OP_SBRA || opcode == OP_ONCE) { /* Checking zero-length iteration. */ if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath); else { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath); } if (opcode != OP_ONCE) free_stack(common, 1); } else JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath); } rminlabel = LABEL(); } else if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); } if (SLJIT_UNLIKELY(opcode == OP_ONCE)) { if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); } once = JUMP(SLJIT_JUMP); } else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { if (has_alternatives) { /* Always exactly one alternative. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); if (SLJIT_UNLIKELY(!jumplistitem)) return; jumplist = jumplistitem; jumplistitem->next = NULL; jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1); } } else if (*cc == OP_ALT) { /* Build a jump list. Get the last successfully matched branch index. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); count = 1; do { /* Append as the last item. */ if (jumplist != NULL) { jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list)); jumplistitem = jumplistitem->next; } else { jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); jumplist = jumplistitem; } if (SLJIT_UNLIKELY(!jumplistitem)) return; jumplistitem->next = NULL; jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++); cc += GET(cc, 1); } while (*cc == OP_ALT); cc = ccbegin + GET(ccbegin, 1); } COMPILE_BACKTRACKPATH(current->top); if (current->topbacktracks) set_jumps(current->topbacktracks, LABEL()); if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { /* Conditional block always has at most one alternative. */ if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) { SLJIT_ASSERT(has_alternatives); assert = CURRENT_AS(bracket_backtrack)->u.assert; if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); } cond = JUMP(SLJIT_JUMP); set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); } else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) { SLJIT_ASSERT(has_alternatives); cond = JUMP(SLJIT_JUMP); set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); } else SLJIT_ASSERT(!has_alternatives); } if (has_alternatives) { count = 1; do { current->top = NULL; current->topbacktracks = NULL; current->nextbacktracks = NULL; if (*cc == OP_ALT) { ccprev = cc + 1 + LINK_SIZE; cc += GET(cc, 1); if (opcode != OP_COND && opcode != OP_SCOND) { if (localptr != 0 && opcode != OP_ONCE) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); else OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } compile_trypath(common, ccprev, cc, current); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; } /* Instructions after the current alternative is succesfully matched. */ /* There is a similar code in compile_bracket_trypath. */ if (opcode == OP_ONCE) { if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); /* TMP2 which is set here used by OP_KETRMAX below. */ if (ket == OP_KETRMAX) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); else if (ket == OP_KETRMIN) { /* Move the STR_PTR to the localptr. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); } } else { OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w)); if (ket == OP_KETRMAX) { /* TMP2 which is set here used by OP_KETRMAX below. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } } } stacksize = 0; if (opcode != OP_ONCE) stacksize++; if (ket != OP_KET || bra != OP_BRA) stacksize++; if (stacksize > 0) { if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0) allocate_stack(common, stacksize); else { /* We know we have place at least for one item on the top of the stack. */ SLJIT_ASSERT(stacksize == 1); OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); } } stacksize = 0; if (ket != OP_KET || bra != OP_BRA) { if (ket != OP_KET) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); else OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); stacksize++; } if (opcode != OP_ONCE) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++); if (offset != 0) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); } JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath); if (opcode != OP_ONCE) { SLJIT_ASSERT(jumplist); JUMPHERE(jumplist->jump); jumplist = jumplist->next; } COMPILE_BACKTRACKPATH(current->top); if (current->topbacktracks) set_jumps(current->topbacktracks, LABEL()); SLJIT_ASSERT(!current->nextbacktracks); } while (*cc == OP_ALT); SLJIT_ASSERT(!jumplist); if (cond != NULL) { SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); assert = CURRENT_AS(bracket_backtrack)->u.assert; if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); } JUMPHERE(cond); } /* Free the STR_PTR. */ if (localptr == 0) free_stack(common, 1); } if (offset != 0) { /* Using both tmp register is better for instruction scheduling. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2)); free_stack(common, 3); } else if (opcode == OP_SBRA || opcode == OP_SCOND) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); } else if (opcode == OP_ONCE) { cc = ccbegin + GET(ccbegin, 1); if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) { /* Reset head and drop saved frame. */ stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1; free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize); } else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) { /* The STR_PTR must be released. */ free_stack(common, 1); } JUMPHERE(once); /* Restore previous localptr */ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w)); else if (ket == OP_KETRMIN) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); /* See the comment below. */ free_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } } if (ket == OP_KETRMAX) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (bra != OP_BRAZERO) free_stack(common, 1); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath); if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); JUMPHERE(brazero); free_stack(common, 1); } } else if (ket == OP_KETRMIN) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); /* OP_ONCE removes everything in case of a backtrack, so we don't need to explicitly release the STR_PTR. The extra release would affect badly the free_stack(2) above. */ if (opcode != OP_ONCE) free_stack(common, 1); CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel); if (opcode == OP_ONCE) free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); else if (bra == OP_BRAMINZERO) free_stack(common, 1); } else if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); JUMPHERE(brazero); } } static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; int offset; struct sljit_jump *jump; if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) { if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) { offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); } set_jumps(current->topbacktracks, LABEL()); free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); return; } OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); if (current->topbacktracks) { jump = JUMP(SLJIT_JUMP); set_jumps(current->topbacktracks, LABEL()); /* Drop the stack frame. */ free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); JUMPHERE(jump); } OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w)); } static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current) { assert_backtrack backtrack; current->top = NULL; current->topbacktracks = NULL; current->nextbacktracks = NULL; if (current->cc[1] > OP_ASSERTBACK_NOT) { /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */ compile_bracket_trypath(common, current->cc, current); compile_bracket_backtrackpath(common, current->top); } else { memset(&backtrack, 0, sizeof(backtrack)); backtrack.common.cc = current->cc; backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath; /* Manual call of compile_assert_trypath. */ compile_assert_trypath(common, current->cc, &backtrack, FALSE); } SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); } static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; while (current) { if (current->nextbacktracks != NULL) set_jumps(current->nextbacktracks, LABEL()); switch(*current->cc) { case OP_SET_SOM: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0); break; case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: case OP_UPTO: case OP_MINUPTO: case OP_EXACT: case OP_POSSTAR: case OP_POSPLUS: case OP_POSQUERY: case OP_POSUPTO: case OP_STARI: case OP_MINSTARI: case OP_PLUSI: case OP_MINPLUSI: case OP_QUERYI: case OP_MINQUERYI: case OP_UPTOI: case OP_MINUPTOI: case OP_EXACTI: case OP_POSSTARI: case OP_POSPLUSI: case OP_POSQUERYI: case OP_POSUPTOI: case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTEXACT: case OP_NOTPOSSTAR: case OP_NOTPOSPLUS: case OP_NOTPOSQUERY: case OP_NOTPOSUPTO: case OP_NOTSTARI: case OP_NOTMINSTARI: case OP_NOTPLUSI: case OP_NOTMINPLUSI: case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTUPTOI: case OP_NOTMINUPTOI: case OP_NOTEXACTI: case OP_NOTPOSSTARI: case OP_NOTPOSPLUSI: case OP_NOTPOSQUERYI: case OP_NOTPOSUPTOI: case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSUPTO: case OP_CLASS: case OP_NCLASS: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: #endif compile_iterator_backtrackpath(common, current); break; case OP_REF: case OP_REFI: compile_ref_iterator_backtrackpath(common, current); break; case OP_RECURSE: compile_recurse_backtrackpath(common, current); break; case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: compile_assert_backtrackpath(common, current); break; case OP_ONCE: case OP_ONCE_NC: case OP_BRA: case OP_CBRA: case OP_COND: case OP_SBRA: case OP_SCBRA: case OP_SCOND: compile_bracket_backtrackpath(common, current); break; case OP_BRAZERO: if (current->cc[1] > OP_ASSERTBACK_NOT) compile_bracket_backtrackpath(common, current); else compile_assert_backtrackpath(common, current); break; case OP_BRAPOS: case OP_CBRAPOS: case OP_SBRAPOS: case OP_SCBRAPOS: case OP_BRAPOSZERO: compile_bracketpos_backtrackpath(common, current); break; case OP_BRAMINZERO: compile_braminzero_backtrackpath(common, current); break; case OP_MARK: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); break; case OP_COMMIT: OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); if (common->leavelabel == NULL) add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP)); else JUMPTO(SLJIT_JUMP, common->leavelabel); break; case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: set_jumps(current->topbacktracks, LABEL()); break; default: SLJIT_ASSERT_STOP(); break; } current = current->prev; } } static SLJIT_INLINE void compile_recurse(compiler_common *common) { DEFINE_COMPILER; pcre_uchar *cc = common->start + common->currententry->start; pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); pcre_uchar *ccend = bracketend(cc); int localsize = get_localsize(common, ccbegin, ccend); int framesize = get_framesize(common, cc, TRUE); int alternativesize; BOOL needsframe; backtrack_common altbacktrack; struct sljit_label *save_leavelabel = common->leavelabel; jump_list *save_leave = common->leave; struct sljit_jump *jump; SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); needsframe = framesize >= 0; if (!needsframe) framesize = 0; alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0); common->currententry->entry = LABEL(); set_jumps(common->currententry->calls, common->currententry->entry); sljit_emit_fast_enter(compiler, TMP2, 0); allocate_stack(common, localsize + framesize + alternativesize); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0); copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0); if (needsframe) init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); if (alternativesize > 0) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); memset(&altbacktrack, 0, sizeof(backtrack_common)); common->leavelabel = NULL; common->acceptlabel = NULL; common->leave = NULL; common->accept = NULL; altbacktrack.cc = ccbegin; cc += GET(cc, 1); while (1) { altbacktrack.top = NULL; altbacktrack.topbacktracks = NULL; if (altbacktrack.cc != ccbegin) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); compile_trypath(common, altbacktrack.cc, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { common->leavelabel = save_leavelabel; common->leave = save_leave; return; } add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); compile_backtrackpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { common->leavelabel = save_leavelabel; common->leave = save_leave; return; } set_jumps(altbacktrack.topbacktracks, LABEL()); if (*cc != OP_ALT) break; altbacktrack.cc = cc + 1 + LINK_SIZE; cc += GET(cc, 1); } /* None of them matched. */ if (common->leave != NULL) set_jumps(common->leave, LABEL()); OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); jump = JUMP(SLJIT_JUMP); set_jumps(common->accept, LABEL()); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head); if (needsframe) { OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); } OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); JUMPHERE(jump); copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize); free_stack(common, localsize + framesize + alternativesize); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); common->leavelabel = save_leavelabel; common->leave = save_leave; } #undef COMPILE_BACKTRACKPATH #undef CURRENT_AS void PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) { struct sljit_compiler *compiler; backtrack_common rootbacktrack; compiler_common common_data; compiler_common *common = &common_data; const pcre_uint8 *tables = re->tables; pcre_study_data *study; int localsize; pcre_uchar *ccend; executable_functions *functions; void *executable_func; sljit_uw executable_size; struct sljit_label *mainloop = NULL; struct sljit_label *empty_match_found; struct sljit_label *empty_match_backtrack; struct sljit_jump *jump; struct sljit_jump *reqbyte_notfound = NULL; struct sljit_jump *empty_match; SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0); study = extra->study_data; if (!tables) tables = PRIV(default_tables); memset(&rootbacktrack, 0, sizeof(backtrack_common)); memset(common, 0, sizeof(compiler_common)); rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; common->start = rootbacktrack.cc; common->fcc = tables + fcc_offset; common->lcc = (sljit_w)(tables + lcc_offset); common->mode = mode; common->nltype = NLTYPE_FIXED; switch(re->options & PCRE_NEWLINE_BITS) { case 0: /* Compile-time default */ switch (NEWLINE) { case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; default: common->newline = NEWLINE; break; } break; case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; case PCRE_NEWLINE_CR+ PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; default: return; } if ((re->options & PCRE_BSR_ANYCRLF) != 0) common->bsr_nltype = NLTYPE_ANYCRLF; else if ((re->options & PCRE_BSR_UNICODE) != 0) common->bsr_nltype = NLTYPE_ANY; else { #ifdef BSR_ANYCRLF common->bsr_nltype = NLTYPE_ANYCRLF; #else common->bsr_nltype = NLTYPE_ANY; #endif } common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; common->ctypes = (sljit_w)(tables + ctypes_offset); common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); common->name_count = re->name_count; common->name_entry_size = re->name_entry_size; common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; #ifdef SUPPORT_UTF /* PCRE_UTF16 has the same value as PCRE_UTF8. */ common->utf = (re->options & PCRE_UTF8) != 0; #ifdef SUPPORT_UCP common->use_ucp = (re->options & PCRE_UCP) != 0; #endif #endif /* SUPPORT_UTF */ ccend = bracketend(rootbacktrack.cc); /* Calculate the local space size on the stack. */ common->ovector_start = CALL_LIMIT + sizeof(sljit_w); SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); localsize = get_localspace(common, rootbacktrack.cc, ccend); if (localsize < 0) return; /* Checking flags and updating ovector_start. */ if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) { common->req_char_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_w); } if (mode != JIT_COMPILE) { common->start_used_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_w); if (mode == JIT_PARTIAL_SOFT_COMPILE) { common->hit_start = common->ovector_start; common->ovector_start += sizeof(sljit_w); } } if ((re->options & PCRE_FIRSTLINE) != 0) { common->first_line_end = common->ovector_start; common->ovector_start += sizeof(sljit_w); } /* Aligning ovector to even number of sljit words. */ if ((common->ovector_start & sizeof(sljit_w)) != 0) common->ovector_start += sizeof(sljit_w); SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); if (localsize > SLJIT_MAX_LOCAL_SIZE) return; common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); if (!common->localptrs) return; memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend); compiler = sljit_create_compiler(); if (!compiler) { SLJIT_FREE(common->localptrs); return; } common->compiler = compiler; /* Main pcre_jit_exec entry. */ sljit_emit_enter(compiler, 1, 5, 5, localsize); /* Register init. */ reset_ovector(common, (re->top_bracket + 1) * 2); if (common->req_char_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0); OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); if (mode == JIT_PARTIAL_SOFT_COMPILE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); /* Main part of the matching */ if ((re->options & PCRE_ANCHORED) == 0) { mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); /* Forward search if possible. */ if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) { if ((re->flags & PCRE_FIRSTSET) != 0) fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); else if ((re->flags & PCRE_STARTLINE) != 0) fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); } } if (common->req_char_ptr != 0) reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); /* Store the current STR_PTR in OVECTOR(0). */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); /* Copy the limit of allowed recursions. */ OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); /* Copy the beginning of the string. */ if (mode == JIT_PARTIAL_SOFT_COMPILE) { jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); JUMPHERE(jump); } else if (mode == JIT_PARTIAL_HARD_COMPILE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); SLJIT_FREE(common->localptrs); return; } empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); empty_match_found = LABEL(); common->acceptlabel = LABEL(); if (common->accept != NULL) set_jumps(common->accept, common->acceptlabel); /* This means we have a match. Update the ovector. */ copy_ovector(common, re->top_bracket + 1); common->leavelabel = LABEL(); if (common->leave != NULL) set_jumps(common->leave, common->leavelabel); sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); if (mode != JIT_COMPILE) { common->partialmatchlabel = LABEL(); set_jumps(common->partialmatch, common->partialmatchlabel); return_with_partial_match(common, common->leavelabel); } empty_match_backtrack = LABEL(); compile_backtrackpath(common, rootbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); SLJIT_FREE(common->localptrs); return; } SLJIT_ASSERT(rootbacktrack.prev == NULL); if (mode == JIT_PARTIAL_SOFT_COMPILE) { /* Update hit_start only in the first time. */ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0); JUMPHERE(jump); } /* Check we have remaining characters. */ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); if ((re->options & PCRE_ANCHORED) == 0) { if ((re->options & PCRE_FIRSTLINE) == 0) { if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) { OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); } else CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); } else { SLJIT_ASSERT(common->first_line_end != 0); if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) { OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL); JUMPTO(SLJIT_C_ZERO, mainloop); } else CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop); } } /* No more remaining characters. */ if (reqbyte_notfound != NULL) JUMPHERE(reqbyte_notfound); if (mode == JIT_PARTIAL_SOFT_COMPILE) CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); JUMPTO(SLJIT_JUMP, common->leavelabel); flush_stubs(common); JUMPHERE(empty_match); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack); OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found); JUMPTO(SLJIT_JUMP, empty_match_backtrack); common->currententry = common->entries; while (common->currententry != NULL) { /* Might add new entries. */ compile_recurse(common); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); SLJIT_FREE(common->localptrs); return; } flush_stubs(common); common->currententry = common->currententry->next; } /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ /* This is a (really) rare case. */ set_jumps(common->stackalloc, LABEL()); /* RETURN_ADDR is not a saved register. */ sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0); OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); /* Allocation failed. */ JUMPHERE(jump); /* We break the return address cache here, but this is a really rare case. */ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); JUMPTO(SLJIT_JUMP, common->leavelabel); /* Call limit reached. */ set_jumps(common->calllimit, LABEL()); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); JUMPTO(SLJIT_JUMP, common->leavelabel); if (common->revertframes != NULL) { set_jumps(common->revertframes, LABEL()); do_revertframes(common); } if (common->wordboundary != NULL) { set_jumps(common->wordboundary, LABEL()); check_wordboundary(common); } if (common->anynewline != NULL) { set_jumps(common->anynewline, LABEL()); check_anynewline(common); } if (common->hspace != NULL) { set_jumps(common->hspace, LABEL()); check_hspace(common); } if (common->vspace != NULL) { set_jumps(common->vspace, LABEL()); check_vspace(common); } if (common->casefulcmp != NULL) { set_jumps(common->casefulcmp, LABEL()); do_casefulcmp(common); } if (common->caselesscmp != NULL) { set_jumps(common->caselesscmp, LABEL()); do_caselesscmp(common); } #ifdef SUPPORT_UTF if (common->utfreadchar != NULL) { set_jumps(common->utfreadchar, LABEL()); do_utfreadchar(common); } #ifdef COMPILE_PCRE8 if (common->utfreadtype8 != NULL) { set_jumps(common->utfreadtype8, LABEL()); do_utfreadtype8(common); } #endif #endif /* COMPILE_PCRE8 */ #ifdef SUPPORT_UCP if (common->getucd != NULL) { set_jumps(common->getucd, LABEL()); do_getucd(common); } #endif SLJIT_FREE(common->localptrs); executable_func = sljit_generate_code(compiler); executable_size = sljit_get_generated_code_size(compiler); sljit_free_compiler(compiler); if (executable_func == NULL) return; /* Reuse the function descriptor if possible. */ if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) functions = (executable_functions *)extra->executable_jit; else { functions = SLJIT_MALLOC(sizeof(executable_functions)); if (functions == NULL) { /* This case is highly unlikely since we just recently freed a lot of memory. Although not impossible. */ sljit_free_code(executable_func); return; } memset(functions, 0, sizeof(executable_functions)); extra->executable_jit = functions; extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; } functions->executable_funcs[mode] = executable_func; functions->executable_sizes[mode] = executable_size; } static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func) { union { void* executable_func; jit_function call_executable_func; } convert_executable_func; pcre_uint8 local_area[LOCAL_SPACE_SIZE]; struct sljit_stack local_stack; local_stack.top = (sljit_w)&local_area; local_stack.base = local_stack.top; local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; local_stack.max_limit = local_stack.limit; arguments->stack = &local_stack; convert_executable_func.executable_func = executable_func; return convert_executable_func.call_executable_func(arguments); } int PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject, int length, int start_offset, int options, int *offsets, int offsetcount) { executable_functions *functions = (executable_functions *)extra_data->executable_jit; union { void* executable_func; jit_function call_executable_func; } convert_executable_func; jit_arguments arguments; int maxoffsetcount; int retval; int mode = JIT_COMPILE; if ((options & PCRE_PARTIAL_HARD) != 0) mode = JIT_PARTIAL_HARD_COMPILE; else if ((options & PCRE_PARTIAL_SOFT) != 0) mode = JIT_PARTIAL_SOFT_COMPILE; if (functions->executable_funcs[mode] == NULL) return PCRE_ERROR_NULL; /* Sanity checks should be handled by pcre_exec. */ arguments.stack = NULL; arguments.str = subject + start_offset; arguments.begin = subject; arguments.end = subject + length; arguments.mark_ptr = NULL; /* JIT decreases this value less frequently than the interpreter. */ arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; arguments.notbol = (options & PCRE_NOTBOL) != 0; arguments.noteol = (options & PCRE_NOTEOL) != 0; arguments.notempty = (options & PCRE_NOTEMPTY) != 0; arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; arguments.offsets = offsets; /* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of the output vector for storing captured strings, with the remainder used as workspace. We don't need the workspace here. For compatibility, we limit the number of captured strings in the same way as pcre_exec(), so that the user gets the same result with and without JIT. */ if (offsetcount != 2) offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3; maxoffsetcount = (re->top_bracket + 1) * 2; if (offsetcount > maxoffsetcount) offsetcount = maxoffsetcount; arguments.offsetcount = offsetcount; if (functions->callback) arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata); else arguments.stack = (struct sljit_stack *)functions->userdata; if (arguments.stack == NULL) retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]); else { convert_executable_func.executable_func = functions->executable_funcs[mode]; retval = convert_executable_func.call_executable_func(&arguments); } if (retval * 2 > offsetcount) retval = 0; if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) *(extra_data->mark) = arguments.mark_ptr; return retval; } void PRIV(jit_free)(void *executable_funcs) { int i; executable_functions *functions = (executable_functions *)executable_funcs; for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) { if (functions->executable_funcs[i] != NULL) sljit_free_code(functions->executable_funcs[i]); } SLJIT_FREE(functions); } int PRIV(jit_get_size)(void *executable_funcs) { int i; sljit_uw size = 0; sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes; for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) size += executable_sizes[i]; return (int)size; } const char* PRIV(jit_get_target)(void) { return sljit_get_platform_name(); } #ifdef COMPILE_PCRE8 PCRE_EXP_DECL pcre_jit_stack * pcre_jit_stack_alloc(int startsize, int maxsize) #else PCRE_EXP_DECL pcre16_jit_stack * pcre16_jit_stack_alloc(int startsize, int maxsize) #endif { if (startsize < 1 || maxsize < 1) return NULL; if (startsize > maxsize) startsize = maxsize; startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize); } #ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *stack) #else PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *stack) #endif { sljit_free_stack((struct sljit_stack *)stack); } #ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) #else PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) #endif { executable_functions *functions; if (extra != NULL && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) { functions = (executable_functions *)extra->executable_jit; functions->callback = callback; functions->userdata = userdata; } } #else /* SUPPORT_JIT */ /* These are dummy functions to avoid linking errors when JIT support is not being compiled. */ #ifdef COMPILE_PCRE8 PCRE_EXP_DECL pcre_jit_stack * pcre_jit_stack_alloc(int startsize, int maxsize) #else PCRE_EXP_DECL pcre16_jit_stack * pcre16_jit_stack_alloc(int startsize, int maxsize) #endif { (void)startsize; (void)maxsize; return NULL; } #ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *stack) #else PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *stack) #endif { (void)stack; } #ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) #else PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) #endif { (void)extra; (void)callback; (void)userdata; } #endif /* End of pcre_jit_compile.c */ pcre-8.31/config.h.generic0000644000222100022210000003062211775533031012344 00000000000000/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, so that config.h is included at the start of every source. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* By default, the \R escape sequence matches any Unicode line ending character or sequence of characters. If BSR_ANYCRLF is defined, this is changed so that backslash-R matches only CR, LF, or CRLF. The build- time default can be overridden by the user of PCRE at runtime. On systems that support it, "configure" can be used to override the default. */ /* #undef BSR_ANYCRLF */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. PCRE will then assume that all input strings are in EBCDIC. If you do not define this macro, PCRE will assume input strings are ASCII or UTF-8/16 Unicode. It is not possible to build a version of PCRE that supports both EBCDIC and UTF-8/16. */ /* #undef EBCDIC */ /* Define to 1 if you have the `bcopy' function. */ #ifndef HAVE_BCOPY #define HAVE_BCOPY 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_BITS_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_BZLIB_H #define HAVE_BZLIB_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_DIRENT_H #define HAVE_DIRENT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_DLFCN_H #define HAVE_DLFCN_H 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_EDITLINE_READLINE_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_EDIT_READLINE_READLINE_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_LIMITS_H #define HAVE_LIMITS_H 1 #endif /* Define to 1 if the system has the type `long long'. */ #ifndef HAVE_LONG_LONG #define HAVE_LONG_LONG 1 #endif /* Define to 1 if you have the `memmove' function. */ #ifndef HAVE_MEMMOVE #define HAVE_MEMMOVE 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_MEMORY_H #define HAVE_MEMORY_H 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_READLINE_HISTORY_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_READLINE_READLINE_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* Define to 1 if you have the `strerror' function. */ #ifndef HAVE_STRERROR #define HAVE_STRERROR 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING #define HAVE_STRING 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRINGS_H #define HAVE_STRINGS_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING_H #define HAVE_STRING_H 1 #endif /* Define to 1 if you have `strtoimax'. */ /* #undef HAVE_STRTOIMAX */ /* Define to 1 if you have `strtoll'. */ /* #undef HAVE_STRTOLL */ /* Define to 1 if you have `strtoq'. */ #ifndef HAVE_STRTOQ #define HAVE_STRTOQ 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_STAT_H #define HAVE_SYS_STAT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_TYPES_H #define HAVE_SYS_TYPES_H 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_UNISTD_H #define HAVE_UNISTD_H 1 #endif /* Define to 1 if the system has the type `unsigned long long'. */ #ifndef HAVE_UNSIGNED_LONG_LONG #define HAVE_UNSIGNED_LONG_LONG 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_ZLIB_H #define HAVE_ZLIB_H 1 #endif /* Define to 1 if you have `_strtoi64'. */ /* #undef HAVE__STRTOI64 */ /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #ifndef LT_OBJDIR #define LT_OBJDIR ".libs/" #endif /* The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default. */ #ifndef MATCH_LIMIT_RECURSION #define MATCH_LIMIT_RECURSION MATCH_LIMIT #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_COUNT #define MAX_NAME_COUNT 10000 #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_SIZE #define MAX_NAME_SIZE 32 #endif /* The value of NEWLINE determines the newline character sequence. On systems that support it, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF). */ #ifndef NEWLINE #define NEWLINE 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #undef NO_RECURSE */ /* Name of package */ #define PACKAGE "pcre" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "PCRE 8.31" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "8.31" /* The value of PCREGREP_BUFSIZE determines the size of buffer used by pcregrep to hold parts of the file it is searching. On systems that support it, "configure" can be used to override the default, which is 8192. This is also the minimum value. The actual amount of memory used by pcregrep is three times this number, because it allows for the buffering of "before" and "after" lines. */ #ifndef PCREGREP_BUFSIZE #define PCREGREP_BUFSIZE 20480 #endif /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ /* #undef PCRE_EXP_DEFN */ /* Define if linking statically (TODO: make nice with Libtool) */ /* #undef PCRE_STATIC */ /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #define STDC_HEADERS 1 #endif /* Define to enable support for Just-In-Time compiling. */ /* #undef SUPPORT_JIT */ /* Define to allow pcregrep to be linked with libbz2, so that it is able to handle .bz2 files. */ /* #undef SUPPORT_LIBBZ2 */ /* Define to allow pcretest to be linked with libedit. */ /* #undef SUPPORT_LIBEDIT */ /* Define to allow pcretest to be linked with libreadline. */ /* #undef SUPPORT_LIBREADLINE */ /* Define to allow pcregrep to be linked with libz, so that it is able to handle .gz files. */ /* #undef SUPPORT_LIBZ */ /* Define to enable the 16 bit PCRE library. */ /* #undef SUPPORT_PCRE16 */ /* Define to enable the 8 bit PCRE library. */ #ifndef SUPPORT_PCRE8 #define SUPPORT_PCRE8 /**/ #endif /* Define to enable JIT support in pcregrep. */ /* #undef SUPPORT_PCREGREP_JIT */ /* Define to enable support for Unicode properties. */ /* #undef SUPPORT_UCP */ /* Define to enable support for the UTF-8/16 Unicode encoding. This will work even in an EBCDIC environment, but it is incompatible with the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8/16, but not both at once. */ /* #undef SUPPORT_UTF */ /* Version number of package */ #ifndef VERSION #define VERSION "8.31" #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to the type of a signed integer type of width exactly 64 bits if such a type exists and the standard includes do not define it. */ /* #undef int64_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ pcre-8.31/Makefile.am0000644000222100022210000003734411770363601011356 00000000000000## Process this file with automake to produce Makefile.in. ACLOCAL_AMFLAGS = -I m4 dist_doc_DATA = \ doc/pcre.txt \ doc/pcre-config.txt \ doc/pcregrep.txt \ doc/pcretest.txt \ AUTHORS \ COPYING \ ChangeLog \ LICENCE \ NEWS \ README dist_html_DATA = \ doc/html/index.html \ doc/html/pcre.html \ doc/html/pcre16.html \ doc/html/pcre-config.html \ doc/html/pcre_assign_jit_stack.html \ doc/html/pcre_compile.html \ doc/html/pcre_compile2.html \ doc/html/pcre_config.html \ doc/html/pcre_copy_named_substring.html \ doc/html/pcre_copy_substring.html \ doc/html/pcre_dfa_exec.html \ doc/html/pcre_exec.html \ doc/html/pcre_free_study.html \ doc/html/pcre_free_substring.html \ doc/html/pcre_free_substring_list.html \ doc/html/pcre_fullinfo.html \ doc/html/pcre_get_named_substring.html \ doc/html/pcre_get_stringnumber.html \ doc/html/pcre_get_stringtable_entries.html \ doc/html/pcre_get_substring.html \ doc/html/pcre_get_substring_list.html \ doc/html/pcre_jit_stack_alloc.html \ doc/html/pcre_jit_stack_free.html \ doc/html/pcre_maketables.html \ doc/html/pcre_pattern_to_host_byte_order.html \ doc/html/pcre_refcount.html \ doc/html/pcre_study.html \ doc/html/pcre_utf16_to_host_byte_order.html \ doc/html/pcre_version.html \ doc/html/pcreapi.html \ doc/html/pcrebuild.html \ doc/html/pcrecallout.html \ doc/html/pcrecompat.html \ doc/html/pcredemo.html \ doc/html/pcregrep.html \ doc/html/pcrejit.html \ doc/html/pcrelimits.html \ doc/html/pcrematching.html \ doc/html/pcrepartial.html \ doc/html/pcrepattern.html \ doc/html/pcreperform.html \ doc/html/pcreposix.html \ doc/html/pcreprecompile.html \ doc/html/pcresample.html \ doc/html/pcrestack.html \ doc/html/pcresyntax.html \ doc/html/pcretest.html \ doc/html/pcreunicode.html pcrecpp_html = doc/html/pcrecpp.html dist_noinst_DATA = $(pcrecpp_html) if WITH_PCRE_CPP html_DATA = $(pcrecpp_html) endif # The Libtool libraries to install. We'll add to this later. lib_LTLIBRARIES = # Unit tests you want to run when people type 'make check'. # TESTS is for binary unit tests, check_SCRIPTS for script-based tests TESTS = check_SCRIPTS = dist_noinst_SCRIPTS = # Some of the binaries we make are to be installed, and others are # (non-user-visible) helper programs needed to build libpcre or libpcre16. bin_PROGRAMS = noinst_PROGRAMS = # Additional files to delete on 'make clean' and 'make maintainer-clean'. CLEANFILES = MAINTAINERCLEANFILES = # Additional files to bundle with the distribution, over and above what # the Autotools include by default. EXTRA_DIST = # These files contain maintenance information EXTRA_DIST += \ doc/perltest.txt \ NON-UNIX-USE \ NON-AUTOTOOLS-BUILD \ HACKING # These files are used in the preparation of a release EXTRA_DIST += \ PrepareRelease \ CheckMan \ CleanTxt \ Detrail \ 132html \ doc/index.html.src # These files are to do with building for Virtual Pascal EXTRA_DIST += \ makevp.bat \ makevp_c.txt \ makevp_l.txt \ pcregexp.pas # These files are usable versions of pcre.h and config.h that are distributed # for the benefit of people who are building PCRE manually, without the # Autotools support. EXTRA_DIST += \ pcre.h.generic \ config.h.generic pcre.h.generic: configure.ac rm -f $@ cp -p pcre.h $@ MAINTAINERCLEANFILES += pcre.h.generic # These are the header files we'll install. We do not distribute pcre.h because # it is generated from pcre.h.in. nodist_include_HEADERS = \ pcre.h include_HEADERS = \ pcreposix.h # These additional headers will be be installed if C++ support is enabled. We # do not distribute pcrecpparg.h or pcre_stringpiece.h, as these are generated # from corresponding .h.in files (which we do distribute). if WITH_PCRE_CPP nodist_include_HEADERS += \ pcrecpparg.h \ pcre_stringpiece.h include_HEADERS += \ pcrecpp.h \ pcre_scanner.h endif # WITH_PCRE_CPP bin_SCRIPTS = pcre-config ## --------------------------------------------------------------- ## The dftables program is used to rebuild character tables before compiling ## PCRE, if --enable-rebuild-chartables is specified. It is not a user-visible ## program. The default (when --enable-rebuild-chartables is not specified) is ## to copy a distributed set of tables that are defined for ASCII code. In this ## case, dftables is not needed. if WITH_REBUILD_CHARTABLES noinst_PROGRAMS += dftables dftables_SOURCES = dftables.c pcre_chartables.c: dftables$(EXEEXT) ./dftables$(EXEEXT) $@ else pcre_chartables.c: $(srcdir)/pcre_chartables.c.dist rm -f $@ $(LN_S) $(srcdir)/pcre_chartables.c.dist $@ endif # WITH_REBUILD_CHARTABLES BUILT_SOURCES = pcre_chartables.c ## The main pcre library # Build the 8 bit library if it is enabled. if WITH_PCRE8 lib_LTLIBRARIES += libpcre.la libpcre_la_SOURCES = \ pcre_byte_order.c \ pcre_compile.c \ pcre_config.c \ pcre_dfa_exec.c \ pcre_exec.c \ pcre_fullinfo.c \ pcre_get.c \ pcre_globals.c \ pcre_internal.h \ pcre_jit_compile.c \ pcre_maketables.c \ pcre_newline.c \ pcre_ord2utf8.c \ pcre_refcount.c \ pcre_string_utils.c \ pcre_study.c \ pcre_tables.c \ pcre_ucd.c \ pcre_valid_utf8.c \ pcre_version.c \ pcre_xclass.c \ ucp.h ## This file is generated as part of the building process, so don't distribute. nodist_libpcre_la_SOURCES = \ pcre_chartables.c endif # WITH_PCRE8 # Build the 16 bit library if it is enabled. if WITH_PCRE16 lib_LTLIBRARIES += libpcre16.la libpcre16_la_SOURCES = \ pcre16_byte_order.c \ pcre16_chartables.c \ pcre16_compile.c \ pcre16_config.c \ pcre16_dfa_exec.c \ pcre16_exec.c \ pcre16_fullinfo.c \ pcre16_get.c \ pcre16_globals.c \ pcre16_jit_compile.c \ pcre16_maketables.c \ pcre16_newline.c \ pcre16_ord2utf16.c \ pcre16_refcount.c \ pcre16_string_utils.c \ pcre16_study.c \ pcre16_tables.c \ pcre16_ucd.c \ pcre16_utf16_utils.c \ pcre16_valid_utf16.c \ pcre16_version.c \ pcre16_xclass.c ## This file is generated as part of the building process, so don't distribute. nodist_libpcre16_la_SOURCES = \ pcre_chartables.c endif # WITH_PCRE16 # The pcre_chartables.c.dist file is the default version of pcre_chartables.c, # used unless --enable-rebuild-chartables is specified. EXTRA_DIST += pcre_chartables.c.dist # The JIT compiler lives in a separate directory, but its files are #included # when pcre_jit_compile.c is processed, so they must be distributed. EXTRA_DIST += \ sljit/sljitConfig.h \ sljit/sljitConfigInternal.h \ sljit/sljitExecAllocator.c \ sljit/sljitLir.c \ sljit/sljitLir.h \ sljit/sljitNativeARM_Thumb2.c \ sljit/sljitNativeARM_v5.c \ sljit/sljitNativeMIPS_32.c \ sljit/sljitNativeMIPS_common.c \ sljit/sljitNativePPC_32.c \ sljit/sljitNativePPC_64.c \ sljit/sljitNativePPC_common.c \ sljit/sljitNativeX86_32.c \ sljit/sljitNativeX86_64.c \ sljit/sljitNativeX86_common.c \ sljit/sljitUtils.c if WITH_PCRE8 libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS) endif # WITH_PCRE8 if WITH_PCRE16 libpcre16_la_LDFLAGS = $(EXTRA_LIBPCRE16_LDFLAGS) endif # WITH_PCRE16 CLEANFILES += pcre_chartables.c ## If JIT support is enabled, arrange for the JIT test program to run. if WITH_JIT TESTS += pcre_jit_test noinst_PROGRAMS += pcre_jit_test pcre_jit_test_SOURCES = pcre_jit_test.c pcre_jit_test_LDADD = if WITH_PCRE8 pcre_jit_test_LDADD += libpcre.la endif # WITH_PCRE8 if WITH_PCRE16 pcre_jit_test_LDADD += libpcre16.la endif # WITH_PCRE16 endif # WITH_JIT ## A version of the main pcre library that has a posix re API. if WITH_PCRE8 lib_LTLIBRARIES += libpcreposix.la libpcreposix_la_SOURCES = \ pcreposix.c libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS) libpcreposix_la_LIBADD = libpcre.la endif # WITH_PCRE8 ## There's a C++ library as well. if WITH_PCRE_CPP lib_LTLIBRARIES += libpcrecpp.la libpcrecpp_la_SOURCES = \ pcrecpp_internal.h \ pcrecpp.cc \ pcre_scanner.cc \ pcre_stringpiece.cc libpcrecpp_la_LDFLAGS = $(EXTRA_LIBPCRECPP_LDFLAGS) libpcrecpp_la_LIBADD = libpcre.la TESTS += pcrecpp_unittest noinst_PROGRAMS += pcrecpp_unittest pcrecpp_unittest_SOURCES = pcrecpp_unittest.cc pcrecpp_unittest_LDADD = libpcrecpp.la TESTS += pcre_scanner_unittest noinst_PROGRAMS += pcre_scanner_unittest pcre_scanner_unittest_SOURCES = pcre_scanner_unittest.cc pcre_scanner_unittest_LDADD = libpcrecpp.la TESTS += pcre_stringpiece_unittest noinst_PROGRAMS += pcre_stringpiece_unittest pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc pcre_stringpiece_unittest_LDADD = libpcrecpp.la endif # WITH_PCRE_CPP ## The main unit tests # Each unit test is a binary plus a script that runs that binary in various # ways. We install these test binaries in case folks find it helpful. TESTS += RunTest dist_noinst_SCRIPTS += RunTest EXTRA_DIST += RunTest.bat bin_PROGRAMS += pcretest pcretest_SOURCES = pcretest.c pcretest_LDADD = $(LIBREADLINE) if WITH_PCRE8 pcretest_SOURCES += pcre_printint.c pcretest_LDADD += libpcre.la libpcreposix.la endif # WITH_PCRE8 if WITH_PCRE16 pcretest_SOURCES += pcre16_printint.c pcretest_LDADD += libpcre16.la endif # WITH_PCRE16 if WITH_PCRE8 TESTS += RunGrepTest dist_noinst_SCRIPTS += RunGrepTest bin_PROGRAMS += pcregrep pcregrep_SOURCES = pcregrep.c pcregrep_LDADD = $(LIBZ) $(LIBBZ2) pcregrep_LDADD += libpcre.la libpcreposix.la endif # WITH_PCRE8 EXTRA_DIST += \ testdata/grepbinary \ testdata/grepfilelist \ testdata/grepinput \ testdata/grepinput3 \ testdata/grepinput8 \ testdata/grepinputv \ testdata/grepinputx \ testdata/greplist \ testdata/grepoutput \ testdata/grepoutput8 \ testdata/grepoutputN \ testdata/greppatN4 \ testdata/saved16 \ testdata/saved16BE-1 \ testdata/saved16BE-2 \ testdata/saved16LE-1 \ testdata/saved16LE-2 \ testdata/saved8 \ testdata/testinput1 \ testdata/testinput2 \ testdata/testinput3 \ testdata/testinput4 \ testdata/testinput5 \ testdata/testinput6 \ testdata/testinput7 \ testdata/testinput8 \ testdata/testinput9 \ testdata/testinput10 \ testdata/testinput11 \ testdata/testinput12 \ testdata/testinput13 \ testdata/testinput14 \ testdata/testinput15 \ testdata/testinput16 \ testdata/testinput17 \ testdata/testinput18 \ testdata/testinput19 \ testdata/testinput20 \ testdata/testinput21 \ testdata/testinput22 \ testdata/testoutput1 \ testdata/testoutput2 \ testdata/testoutput3 \ testdata/testoutput4 \ testdata/testoutput5 \ testdata/testoutput6 \ testdata/testoutput7 \ testdata/testoutput8 \ testdata/testoutput9 \ testdata/testoutput10 \ testdata/testoutput11-16 \ testdata/testoutput11-8 \ testdata/testoutput12 \ testdata/testoutput13 \ testdata/testoutput14 \ testdata/testoutput15 \ testdata/testoutput16 \ testdata/testoutput17 \ testdata/testoutput18 \ testdata/testoutput19 \ testdata/testoutput20 \ testdata/testoutput21 \ testdata/testoutput22 \ testdata/wintestinput3 \ testdata/wintestoutput3 \ perltest.pl CLEANFILES += \ testsavedregex \ teststderr \ testtry \ testNinput # PCRE demonstration program. No longer built automatcally. The point is that # the users should build it themselves. So just distribute the source. # noinst_PROGRAMS += pcredemo # pcredemo_SOURCES = pcredemo.c # pcredemo_LDADD = libpcre.la EXTRA_DIST += pcredemo.c ## Utility rules, documentation, etc. # A compatibility line, the old build system worked with 'make test' test: check ; # A PCRE user submitted the following addition, saying that it "will allow # anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a # nice DLL for Windows use". (It is used by the pcre.dll target.) DLL_OBJS= pcre_byte_order.o pcre_compile.o pcre_config.o \ pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \ pcre_globals.o pcre_jit_compile.o pcre_maketables.o \ pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \ pcre_study.o pcre_tables.o pcre_ucd.o \ pcre_valid_utf8.o pcre_version.o pcre_chartables.o \ pcre_xclass.o # A PCRE user submitted the following addition, saying that it "will allow # anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a # nice DLL for Windows use". pcre.dll: $(DLL_OBJS) $(CC) -shared -o pcre.dll -Wl,"--strip-all" -Wl,"--export-all-symbols" $(DLL_OBJS) # We have .pc files for pkg-config users. pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpcre.pc libpcreposix.pc if WITH_PCRE16 pkgconfig_DATA += libpcre16.pc endif if WITH_PCRE_CPP pkgconfig_DATA += libpcrecpp.pc endif dist_man_MANS = \ doc/pcre.3 \ doc/pcre16.3 \ doc/pcre-config.1 \ doc/pcre_assign_jit_stack.3 \ doc/pcre_compile.3 \ doc/pcre_compile2.3 \ doc/pcre_config.3 \ doc/pcre_copy_named_substring.3 \ doc/pcre_copy_substring.3 \ doc/pcre_dfa_exec.3 \ doc/pcre_exec.3 \ doc/pcre_free_study.3 \ doc/pcre_free_substring.3 \ doc/pcre_free_substring_list.3 \ doc/pcre_fullinfo.3 \ doc/pcre_get_named_substring.3 \ doc/pcre_get_stringnumber.3 \ doc/pcre_get_stringtable_entries.3 \ doc/pcre_get_substring.3 \ doc/pcre_get_substring_list.3 \ doc/pcre_jit_stack_alloc.3 \ doc/pcre_jit_stack_free.3 \ doc/pcre_maketables.3 \ doc/pcre_pattern_to_host_byte_order.3 \ doc/pcre_refcount.3 \ doc/pcre_study.3 \ doc/pcre_utf16_to_host_byte_order.3 \ doc/pcre_version.3 \ doc/pcreapi.3 \ doc/pcrebuild.3 \ doc/pcrecallout.3 \ doc/pcrecompat.3 \ doc/pcregrep.1 \ doc/pcrejit.3 \ doc/pcrelimits.3 \ doc/pcrematching.3 \ doc/pcrepartial.3 \ doc/pcrepattern.3 \ doc/pcreperform.3 \ doc/pcreposix.3 \ doc/pcreprecompile.3 \ doc/pcresample.3 \ doc/pcrestack.3 \ doc/pcresyntax.3 \ doc/pcretest.1 \ doc/pcreunicode.3 # Arrange for the per-function man pages to have 16-bit names as well. install-data-hook: ln -sf pcre_assign_jit_stack.3 $(DESTDIR)$(man3dir)/pcre16_assign_jit_stack.3 ln -sf pcre_compile.3 $(DESTDIR)$(man3dir)/pcre16_compile.3 ln -sf pcre_compile2.3 $(DESTDIR)$(man3dir)/pcre16_compile2.3 ln -sf pcre_config.3 $(DESTDIR)$(man3dir)/pcre16_config.3 ln -sf pcre_copy_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_named_substring.3 ln -sf pcre_copy_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_substring.3 ln -sf pcre_dfa_exec.3 $(DESTDIR)$(man3dir)/pcre16_dfa_exec.3 ln -sf pcre_exec.3 $(DESTDIR)$(man3dir)/pcre16_exec.3 ln -sf pcre_free_study.3 $(DESTDIR)$(man3dir)/pcre16_free_study.3 ln -sf pcre_free_substring.3 $(DESTDIR)$(man3dir)/pcre16_free_substring.3 ln -sf pcre_free_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_free_substring_list.3 ln -sf pcre_fullinfo.3 $(DESTDIR)$(man3dir)/pcre16_fullinfo.3 ln -sf pcre_get_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_named_substring.3 ln -sf pcre_get_stringnumber.3 $(DESTDIR)$(man3dir)/pcre16_get_stringnumber.3 ln -sf pcre_get_stringtable_entries.3 $(DESTDIR)$(man3dir)/pcre16_get_stringtable_entries.3 ln -sf pcre_get_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_substring.3 ln -sf pcre_get_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_get_substring_list.3 ln -sf pcre_jit_stack_alloc.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_alloc.3 ln -sf pcre_jit_stack_free.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_free.3 ln -sf pcre_maketables.3 $(DESTDIR)$(man3dir)/pcre16_maketables.3 ln -sf pcre_pattern_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_pattern_to_host_byte_order.3 ln -sf pcre_refcount.3 $(DESTDIR)$(man3dir)/pcre16_refcount.3 ln -sf pcre_study.3 $(DESTDIR)$(man3dir)/pcre16_study.3 ln -sf pcre_utf16_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_utf16_to_host_byte_order.3 ln -sf pcre_version.3 $(DESTDIR)$(man3dir)/pcre16_version.3 pcrecpp_man = doc/pcrecpp.3 EXTRA_DIST += $(pcrecpp_man) if WITH_PCRE_CPP man_MANS = $(pcrecpp_man) endif ## CMake support EXTRA_DIST += \ cmake/COPYING-CMAKE-SCRIPTS \ cmake/FindPackageHandleStandardArgs.cmake \ cmake/FindReadline.cmake \ cmake/FindEditline.cmake \ CMakeLists.txt \ config-cmake.h.in ## end Makefile.am pcre-8.31/Makefile.in0000644000222100022210000022030311775533020011353 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ TESTS = $(am__EXEEXT_3) $(am__EXEEXT_4) RunTest $(am__append_18) bin_PROGRAMS = pcretest$(EXEEXT) $(am__EXEEXT_1) noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) # These additional headers will be be installed if C++ support is enabled. We # do not distribute pcrecpparg.h or pcre_stringpiece.h, as these are generated # from corresponding .h.in files (which we do distribute). @WITH_PCRE_CPP_TRUE@am__append_1 = \ @WITH_PCRE_CPP_TRUE@ pcrecpparg.h \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece.h @WITH_PCRE_CPP_TRUE@am__append_2 = \ @WITH_PCRE_CPP_TRUE@ pcrecpp.h \ @WITH_PCRE_CPP_TRUE@ pcre_scanner.h @WITH_REBUILD_CHARTABLES_TRUE@am__append_3 = dftables # Build the 8 bit library if it is enabled. @WITH_PCRE8_TRUE@am__append_4 = libpcre.la # Build the 16 bit library if it is enabled. @WITH_PCRE16_TRUE@am__append_5 = libpcre16.la @WITH_JIT_TRUE@am__append_6 = pcre_jit_test @WITH_JIT_TRUE@am__append_7 = pcre_jit_test @WITH_JIT_TRUE@@WITH_PCRE8_TRUE@am__append_8 = libpcre.la @WITH_JIT_TRUE@@WITH_PCRE16_TRUE@am__append_9 = libpcre16.la @WITH_PCRE8_TRUE@am__append_10 = libpcreposix.la @WITH_PCRE_CPP_TRUE@am__append_11 = libpcrecpp.la @WITH_PCRE_CPP_TRUE@am__append_12 = pcrecpp_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest @WITH_PCRE_CPP_TRUE@am__append_13 = pcrecpp_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest @WITH_PCRE8_TRUE@am__append_14 = pcre_printint.c @WITH_PCRE8_TRUE@am__append_15 = libpcre.la libpcreposix.la @WITH_PCRE16_TRUE@am__append_16 = pcre16_printint.c @WITH_PCRE16_TRUE@am__append_17 = libpcre16.la @WITH_PCRE8_TRUE@am__append_18 = RunGrepTest @WITH_PCRE8_TRUE@am__append_19 = RunGrepTest @WITH_PCRE8_TRUE@am__append_20 = pcregrep @WITH_PCRE16_TRUE@am__append_21 = libpcre16.pc @WITH_PCRE_CPP_TRUE@am__append_22 = libpcrecpp.pc subdir = . DIST_COMMON = README $(am__configure_deps) \ $(am__dist_noinst_SCRIPTS_DIST) $(am__include_HEADERS_DIST) \ $(dist_doc_DATA) $(dist_html_DATA) $(dist_man_MANS) \ $(dist_noinst_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/libpcre.pc.in $(srcdir)/libpcre16.pc.in \ $(srcdir)/libpcrecpp.pc.in $(srcdir)/libpcreposix.pc.in \ $(srcdir)/pcre-config.in $(srcdir)/pcre.h.in \ $(srcdir)/pcre_stringpiece.h.in $(srcdir)/pcrecpparg.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ config.guess config.sub depcomp install-sh ltmain.sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = libpcre.pc libpcre16.pc libpcreposix.pc \ libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h \ pcrecpparg.h CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)" \ "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libpcre_la_LIBADD = am__libpcre_la_SOURCES_DIST = pcre_byte_order.c pcre_compile.c \ pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c \ pcre_get.c pcre_globals.c pcre_internal.h pcre_jit_compile.c \ pcre_maketables.c pcre_newline.c pcre_ord2utf8.c \ pcre_refcount.c pcre_string_utils.c pcre_study.c pcre_tables.c \ pcre_ucd.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c \ ucp.h @WITH_PCRE8_TRUE@am_libpcre_la_OBJECTS = pcre_byte_order.lo \ @WITH_PCRE8_TRUE@ pcre_compile.lo pcre_config.lo \ @WITH_PCRE8_TRUE@ pcre_dfa_exec.lo pcre_exec.lo \ @WITH_PCRE8_TRUE@ pcre_fullinfo.lo pcre_get.lo pcre_globals.lo \ @WITH_PCRE8_TRUE@ pcre_jit_compile.lo pcre_maketables.lo \ @WITH_PCRE8_TRUE@ pcre_newline.lo pcre_ord2utf8.lo \ @WITH_PCRE8_TRUE@ pcre_refcount.lo pcre_string_utils.lo \ @WITH_PCRE8_TRUE@ pcre_study.lo pcre_tables.lo pcre_ucd.lo \ @WITH_PCRE8_TRUE@ pcre_valid_utf8.lo pcre_version.lo \ @WITH_PCRE8_TRUE@ pcre_xclass.lo @WITH_PCRE8_TRUE@nodist_libpcre_la_OBJECTS = pcre_chartables.lo libpcre_la_OBJECTS = $(am_libpcre_la_OBJECTS) \ $(nodist_libpcre_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent libpcre_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libpcre_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_PCRE8_TRUE@am_libpcre_la_rpath = -rpath $(libdir) libpcre16_la_LIBADD = am__libpcre16_la_SOURCES_DIST = pcre16_byte_order.c \ pcre16_chartables.c pcre16_compile.c pcre16_config.c \ pcre16_dfa_exec.c pcre16_exec.c pcre16_fullinfo.c pcre16_get.c \ pcre16_globals.c pcre16_jit_compile.c pcre16_maketables.c \ pcre16_newline.c pcre16_ord2utf16.c pcre16_refcount.c \ pcre16_string_utils.c pcre16_study.c pcre16_tables.c \ pcre16_ucd.c pcre16_utf16_utils.c pcre16_valid_utf16.c \ pcre16_version.c pcre16_xclass.c @WITH_PCRE16_TRUE@am_libpcre16_la_OBJECTS = pcre16_byte_order.lo \ @WITH_PCRE16_TRUE@ pcre16_chartables.lo pcre16_compile.lo \ @WITH_PCRE16_TRUE@ pcre16_config.lo pcre16_dfa_exec.lo \ @WITH_PCRE16_TRUE@ pcre16_exec.lo pcre16_fullinfo.lo \ @WITH_PCRE16_TRUE@ pcre16_get.lo pcre16_globals.lo \ @WITH_PCRE16_TRUE@ pcre16_jit_compile.lo pcre16_maketables.lo \ @WITH_PCRE16_TRUE@ pcre16_newline.lo pcre16_ord2utf16.lo \ @WITH_PCRE16_TRUE@ pcre16_refcount.lo pcre16_string_utils.lo \ @WITH_PCRE16_TRUE@ pcre16_study.lo pcre16_tables.lo \ @WITH_PCRE16_TRUE@ pcre16_ucd.lo pcre16_utf16_utils.lo \ @WITH_PCRE16_TRUE@ pcre16_valid_utf16.lo pcre16_version.lo \ @WITH_PCRE16_TRUE@ pcre16_xclass.lo @WITH_PCRE16_TRUE@nodist_libpcre16_la_OBJECTS = pcre_chartables.lo libpcre16_la_OBJECTS = $(am_libpcre16_la_OBJECTS) \ $(nodist_libpcre16_la_OBJECTS) libpcre16_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libpcre16_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_PCRE16_TRUE@am_libpcre16_la_rpath = -rpath $(libdir) @WITH_PCRE_CPP_TRUE@libpcrecpp_la_DEPENDENCIES = libpcre.la am__libpcrecpp_la_SOURCES_DIST = pcrecpp_internal.h pcrecpp.cc \ pcre_scanner.cc pcre_stringpiece.cc @WITH_PCRE_CPP_TRUE@am_libpcrecpp_la_OBJECTS = pcrecpp.lo \ @WITH_PCRE_CPP_TRUE@ pcre_scanner.lo pcre_stringpiece.lo libpcrecpp_la_OBJECTS = $(am_libpcrecpp_la_OBJECTS) libpcrecpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libpcrecpp_la_LDFLAGS) $(LDFLAGS) \ -o $@ @WITH_PCRE_CPP_TRUE@am_libpcrecpp_la_rpath = -rpath $(libdir) @WITH_PCRE8_TRUE@libpcreposix_la_DEPENDENCIES = libpcre.la am__libpcreposix_la_SOURCES_DIST = pcreposix.c @WITH_PCRE8_TRUE@am_libpcreposix_la_OBJECTS = pcreposix.lo libpcreposix_la_OBJECTS = $(am_libpcreposix_la_OBJECTS) libpcreposix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libpcreposix_la_LDFLAGS) $(LDFLAGS) \ -o $@ @WITH_PCRE8_TRUE@am_libpcreposix_la_rpath = -rpath $(libdir) @WITH_PCRE8_TRUE@am__EXEEXT_1 = pcregrep$(EXEEXT) @WITH_REBUILD_CHARTABLES_TRUE@am__EXEEXT_2 = dftables$(EXEEXT) @WITH_JIT_TRUE@am__EXEEXT_3 = pcre_jit_test$(EXEEXT) @WITH_PCRE_CPP_TRUE@am__EXEEXT_4 = pcrecpp_unittest$(EXEEXT) \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest$(EXEEXT) \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) am__dftables_SOURCES_DIST = dftables.c @WITH_REBUILD_CHARTABLES_TRUE@am_dftables_OBJECTS = \ @WITH_REBUILD_CHARTABLES_TRUE@ dftables.$(OBJEXT) dftables_OBJECTS = $(am_dftables_OBJECTS) dftables_LDADD = $(LDADD) am__pcre_jit_test_SOURCES_DIST = pcre_jit_test.c @WITH_JIT_TRUE@am_pcre_jit_test_OBJECTS = pcre_jit_test.$(OBJEXT) pcre_jit_test_OBJECTS = $(am_pcre_jit_test_OBJECTS) @WITH_JIT_TRUE@pcre_jit_test_DEPENDENCIES = $(am__append_8) \ @WITH_JIT_TRUE@ $(am__append_9) am__pcre_scanner_unittest_SOURCES_DIST = pcre_scanner_unittest.cc @WITH_PCRE_CPP_TRUE@am_pcre_scanner_unittest_OBJECTS = \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest.$(OBJEXT) pcre_scanner_unittest_OBJECTS = $(am_pcre_scanner_unittest_OBJECTS) @WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_DEPENDENCIES = \ @WITH_PCRE_CPP_TRUE@ libpcrecpp.la am__pcre_stringpiece_unittest_SOURCES_DIST = \ pcre_stringpiece_unittest.cc @WITH_PCRE_CPP_TRUE@am_pcre_stringpiece_unittest_OBJECTS = \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest.$(OBJEXT) pcre_stringpiece_unittest_OBJECTS = \ $(am_pcre_stringpiece_unittest_OBJECTS) @WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_DEPENDENCIES = \ @WITH_PCRE_CPP_TRUE@ libpcrecpp.la am__pcrecpp_unittest_SOURCES_DIST = pcrecpp_unittest.cc @WITH_PCRE_CPP_TRUE@am_pcrecpp_unittest_OBJECTS = \ @WITH_PCRE_CPP_TRUE@ pcrecpp_unittest.$(OBJEXT) pcrecpp_unittest_OBJECTS = $(am_pcrecpp_unittest_OBJECTS) @WITH_PCRE_CPP_TRUE@pcrecpp_unittest_DEPENDENCIES = libpcrecpp.la am__pcregrep_SOURCES_DIST = pcregrep.c @WITH_PCRE8_TRUE@am_pcregrep_OBJECTS = pcregrep.$(OBJEXT) pcregrep_OBJECTS = $(am_pcregrep_OBJECTS) am__DEPENDENCIES_1 = @WITH_PCRE8_TRUE@pcregrep_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @WITH_PCRE8_TRUE@ $(am__DEPENDENCIES_1) libpcre.la \ @WITH_PCRE8_TRUE@ libpcreposix.la am__pcretest_SOURCES_DIST = pcretest.c pcre_printint.c \ pcre16_printint.c @WITH_PCRE8_TRUE@am__objects_1 = pcre_printint.$(OBJEXT) @WITH_PCRE16_TRUE@am__objects_2 = pcre16_printint.$(OBJEXT) am_pcretest_OBJECTS = pcretest.$(OBJEXT) $(am__objects_1) \ $(am__objects_2) pcretest_OBJECTS = $(am_pcretest_OBJECTS) pcretest_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_15) \ $(am__append_17) am__dist_noinst_SCRIPTS_DIST = RunTest RunGrepTest SCRIPTS = $(bin_SCRIPTS) $(dist_noinst_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_$(V)) am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) am__v_CC_0 = @echo " CC " $@; AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_$(V)) am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) am__v_CCLD_0 = @echo " CCLD " $@; CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_$(V)) am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY)) am__v_CXX_0 = @echo " CXX " $@; CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_$(V)) am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY)) am__v_CXXLD_0 = @echo " CXXLD " $@; AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libpcre_la_SOURCES) $(nodist_libpcre_la_SOURCES) \ $(libpcre16_la_SOURCES) $(nodist_libpcre16_la_SOURCES) \ $(libpcrecpp_la_SOURCES) $(libpcreposix_la_SOURCES) \ $(dftables_SOURCES) $(pcre_jit_test_SOURCES) \ $(pcre_scanner_unittest_SOURCES) \ $(pcre_stringpiece_unittest_SOURCES) \ $(pcrecpp_unittest_SOURCES) $(pcregrep_SOURCES) \ $(pcretest_SOURCES) DIST_SOURCES = $(am__libpcre_la_SOURCES_DIST) \ $(am__libpcre16_la_SOURCES_DIST) \ $(am__libpcrecpp_la_SOURCES_DIST) \ $(am__libpcreposix_la_SOURCES_DIST) \ $(am__dftables_SOURCES_DIST) $(am__pcre_jit_test_SOURCES_DIST) \ $(am__pcre_scanner_unittest_SOURCES_DIST) \ $(am__pcre_stringpiece_unittest_SOURCES_DIST) \ $(am__pcrecpp_unittest_SOURCES_DIST) \ $(am__pcregrep_SOURCES_DIST) $(am__pcretest_SOURCES_DIST) man1dir = $(mandir)/man1 man3dir = $(mandir)/man3 NROFF = nroff MANS = $(dist_man_MANS) $(man_MANS) DATA = $(dist_doc_DATA) $(dist_html_DATA) $(dist_noinst_DATA) \ $(html_DATA) $(pkgconfig_DATA) am__include_HEADERS_DIST = pcreposix.h pcrecpp.h pcre_scanner.h HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) ETAGS = etags CTAGS = ctags am__tty_colors = \ red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBPCRE16_LDFLAGS = @EXTRA_LIBPCRE16_LDFLAGS@ EXTRA_LIBPCRECPP_LDFLAGS = @EXTRA_LIBPCRECPP_LDFLAGS@ EXTRA_LIBPCREPOSIX_LDFLAGS = @EXTRA_LIBPCREPOSIX_LDFLAGS@ EXTRA_LIBPCRE_LDFLAGS = @EXTRA_LIBPCRE_LDFLAGS@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBZ2 = @LIBBZ2@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZ = @LIBZ@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_DATE = @PCRE_DATE@ PCRE_MAJOR = @PCRE_MAJOR@ PCRE_MINOR = @PCRE_MINOR@ PCRE_PRERELEASE = @PCRE_PRERELEASE@ PCRE_STATIC_CFLAG = @PCRE_STATIC_CFLAG@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_cpp = @enable_cpp@ enable_pcre16 = @enable_pcre16@ enable_pcre8 = @enable_pcre8@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pcre_have_bits_type_traits = @pcre_have_bits_type_traits@ pcre_have_long_long = @pcre_have_long_long@ pcre_have_type_traits = @pcre_have_type_traits@ pcre_have_ulong_long = @pcre_have_ulong_long@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 dist_doc_DATA = \ doc/pcre.txt \ doc/pcre-config.txt \ doc/pcregrep.txt \ doc/pcretest.txt \ AUTHORS \ COPYING \ ChangeLog \ LICENCE \ NEWS \ README dist_html_DATA = \ doc/html/index.html \ doc/html/pcre.html \ doc/html/pcre16.html \ doc/html/pcre-config.html \ doc/html/pcre_assign_jit_stack.html \ doc/html/pcre_compile.html \ doc/html/pcre_compile2.html \ doc/html/pcre_config.html \ doc/html/pcre_copy_named_substring.html \ doc/html/pcre_copy_substring.html \ doc/html/pcre_dfa_exec.html \ doc/html/pcre_exec.html \ doc/html/pcre_free_study.html \ doc/html/pcre_free_substring.html \ doc/html/pcre_free_substring_list.html \ doc/html/pcre_fullinfo.html \ doc/html/pcre_get_named_substring.html \ doc/html/pcre_get_stringnumber.html \ doc/html/pcre_get_stringtable_entries.html \ doc/html/pcre_get_substring.html \ doc/html/pcre_get_substring_list.html \ doc/html/pcre_jit_stack_alloc.html \ doc/html/pcre_jit_stack_free.html \ doc/html/pcre_maketables.html \ doc/html/pcre_pattern_to_host_byte_order.html \ doc/html/pcre_refcount.html \ doc/html/pcre_study.html \ doc/html/pcre_utf16_to_host_byte_order.html \ doc/html/pcre_version.html \ doc/html/pcreapi.html \ doc/html/pcrebuild.html \ doc/html/pcrecallout.html \ doc/html/pcrecompat.html \ doc/html/pcredemo.html \ doc/html/pcregrep.html \ doc/html/pcrejit.html \ doc/html/pcrelimits.html \ doc/html/pcrematching.html \ doc/html/pcrepartial.html \ doc/html/pcrepattern.html \ doc/html/pcreperform.html \ doc/html/pcreposix.html \ doc/html/pcreprecompile.html \ doc/html/pcresample.html \ doc/html/pcrestack.html \ doc/html/pcresyntax.html \ doc/html/pcretest.html \ doc/html/pcreunicode.html pcrecpp_html = doc/html/pcrecpp.html dist_noinst_DATA = $(pcrecpp_html) @WITH_PCRE_CPP_TRUE@html_DATA = $(pcrecpp_html) # The Libtool libraries to install. We'll add to this later. lib_LTLIBRARIES = $(am__append_4) $(am__append_5) $(am__append_10) \ $(am__append_11) check_SCRIPTS = dist_noinst_SCRIPTS = RunTest $(am__append_19) # Additional files to delete on 'make clean' and 'make maintainer-clean'. CLEANFILES = pcre_chartables.c testsavedregex teststderr testtry \ testNinput MAINTAINERCLEANFILES = pcre.h.generic # Additional files to bundle with the distribution, over and above what # the Autotools include by default. # These files contain maintenance information # These files are used in the preparation of a release # These files are to do with building for Virtual Pascal # These files are usable versions of pcre.h and config.h that are distributed # for the benefit of people who are building PCRE manually, without the # Autotools support. # The pcre_chartables.c.dist file is the default version of pcre_chartables.c, # used unless --enable-rebuild-chartables is specified. # The JIT compiler lives in a separate directory, but its files are #included # when pcre_jit_compile.c is processed, so they must be distributed. # PCRE demonstration program. No longer built automatcally. The point is that # the users should build it themselves. So just distribute the source. # noinst_PROGRAMS += pcredemo # pcredemo_SOURCES = pcredemo.c # pcredemo_LDADD = libpcre.la EXTRA_DIST = doc/perltest.txt NON-UNIX-USE NON-AUTOTOOLS-BUILD HACKING \ PrepareRelease CheckMan CleanTxt Detrail 132html \ doc/index.html.src makevp.bat makevp_c.txt makevp_l.txt \ pcregexp.pas pcre.h.generic config.h.generic \ pcre_chartables.c.dist sljit/sljitConfig.h \ sljit/sljitConfigInternal.h sljit/sljitExecAllocator.c \ sljit/sljitLir.c sljit/sljitLir.h \ sljit/sljitNativeARM_Thumb2.c sljit/sljitNativeARM_v5.c \ sljit/sljitNativeMIPS_32.c sljit/sljitNativeMIPS_common.c \ sljit/sljitNativePPC_32.c sljit/sljitNativePPC_64.c \ sljit/sljitNativePPC_common.c sljit/sljitNativeX86_32.c \ sljit/sljitNativeX86_64.c sljit/sljitNativeX86_common.c \ sljit/sljitUtils.c RunTest.bat testdata/grepbinary \ testdata/grepfilelist testdata/grepinput testdata/grepinput3 \ testdata/grepinput8 testdata/grepinputv testdata/grepinputx \ testdata/greplist testdata/grepoutput testdata/grepoutput8 \ testdata/grepoutputN testdata/greppatN4 testdata/saved16 \ testdata/saved16BE-1 testdata/saved16BE-2 testdata/saved16LE-1 \ testdata/saved16LE-2 testdata/saved8 testdata/testinput1 \ testdata/testinput2 testdata/testinput3 testdata/testinput4 \ testdata/testinput5 testdata/testinput6 testdata/testinput7 \ testdata/testinput8 testdata/testinput9 testdata/testinput10 \ testdata/testinput11 testdata/testinput12 testdata/testinput13 \ testdata/testinput14 testdata/testinput15 testdata/testinput16 \ testdata/testinput17 testdata/testinput18 testdata/testinput19 \ testdata/testinput20 testdata/testinput21 testdata/testinput22 \ testdata/testoutput1 testdata/testoutput2 testdata/testoutput3 \ testdata/testoutput4 testdata/testoutput5 testdata/testoutput6 \ testdata/testoutput7 testdata/testoutput8 testdata/testoutput9 \ testdata/testoutput10 testdata/testoutput11-16 \ testdata/testoutput11-8 testdata/testoutput12 \ testdata/testoutput13 testdata/testoutput14 \ testdata/testoutput15 testdata/testoutput16 \ testdata/testoutput17 testdata/testoutput18 \ testdata/testoutput19 testdata/testoutput20 \ testdata/testoutput21 testdata/testoutput22 \ testdata/wintestinput3 testdata/wintestoutput3 perltest.pl \ pcredemo.c $(pcrecpp_man) cmake/COPYING-CMAKE-SCRIPTS \ cmake/FindPackageHandleStandardArgs.cmake \ cmake/FindReadline.cmake cmake/FindEditline.cmake \ CMakeLists.txt config-cmake.h.in # These are the header files we'll install. We do not distribute pcre.h because # it is generated from pcre.h.in. nodist_include_HEADERS = pcre.h $(am__append_1) include_HEADERS = pcreposix.h $(am__append_2) bin_SCRIPTS = pcre-config @WITH_REBUILD_CHARTABLES_TRUE@dftables_SOURCES = dftables.c BUILT_SOURCES = pcre_chartables.c @WITH_PCRE8_TRUE@libpcre_la_SOURCES = \ @WITH_PCRE8_TRUE@ pcre_byte_order.c \ @WITH_PCRE8_TRUE@ pcre_compile.c \ @WITH_PCRE8_TRUE@ pcre_config.c \ @WITH_PCRE8_TRUE@ pcre_dfa_exec.c \ @WITH_PCRE8_TRUE@ pcre_exec.c \ @WITH_PCRE8_TRUE@ pcre_fullinfo.c \ @WITH_PCRE8_TRUE@ pcre_get.c \ @WITH_PCRE8_TRUE@ pcre_globals.c \ @WITH_PCRE8_TRUE@ pcre_internal.h \ @WITH_PCRE8_TRUE@ pcre_jit_compile.c \ @WITH_PCRE8_TRUE@ pcre_maketables.c \ @WITH_PCRE8_TRUE@ pcre_newline.c \ @WITH_PCRE8_TRUE@ pcre_ord2utf8.c \ @WITH_PCRE8_TRUE@ pcre_refcount.c \ @WITH_PCRE8_TRUE@ pcre_string_utils.c \ @WITH_PCRE8_TRUE@ pcre_study.c \ @WITH_PCRE8_TRUE@ pcre_tables.c \ @WITH_PCRE8_TRUE@ pcre_ucd.c \ @WITH_PCRE8_TRUE@ pcre_valid_utf8.c \ @WITH_PCRE8_TRUE@ pcre_version.c \ @WITH_PCRE8_TRUE@ pcre_xclass.c \ @WITH_PCRE8_TRUE@ ucp.h @WITH_PCRE8_TRUE@nodist_libpcre_la_SOURCES = \ @WITH_PCRE8_TRUE@ pcre_chartables.c @WITH_PCRE16_TRUE@libpcre16_la_SOURCES = \ @WITH_PCRE16_TRUE@ pcre16_byte_order.c \ @WITH_PCRE16_TRUE@ pcre16_chartables.c \ @WITH_PCRE16_TRUE@ pcre16_compile.c \ @WITH_PCRE16_TRUE@ pcre16_config.c \ @WITH_PCRE16_TRUE@ pcre16_dfa_exec.c \ @WITH_PCRE16_TRUE@ pcre16_exec.c \ @WITH_PCRE16_TRUE@ pcre16_fullinfo.c \ @WITH_PCRE16_TRUE@ pcre16_get.c \ @WITH_PCRE16_TRUE@ pcre16_globals.c \ @WITH_PCRE16_TRUE@ pcre16_jit_compile.c \ @WITH_PCRE16_TRUE@ pcre16_maketables.c \ @WITH_PCRE16_TRUE@ pcre16_newline.c \ @WITH_PCRE16_TRUE@ pcre16_ord2utf16.c \ @WITH_PCRE16_TRUE@ pcre16_refcount.c \ @WITH_PCRE16_TRUE@ pcre16_string_utils.c \ @WITH_PCRE16_TRUE@ pcre16_study.c \ @WITH_PCRE16_TRUE@ pcre16_tables.c \ @WITH_PCRE16_TRUE@ pcre16_ucd.c \ @WITH_PCRE16_TRUE@ pcre16_utf16_utils.c \ @WITH_PCRE16_TRUE@ pcre16_valid_utf16.c \ @WITH_PCRE16_TRUE@ pcre16_version.c \ @WITH_PCRE16_TRUE@ pcre16_xclass.c @WITH_PCRE16_TRUE@nodist_libpcre16_la_SOURCES = \ @WITH_PCRE16_TRUE@ pcre_chartables.c @WITH_PCRE8_TRUE@libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS) @WITH_PCRE16_TRUE@libpcre16_la_LDFLAGS = $(EXTRA_LIBPCRE16_LDFLAGS) @WITH_JIT_TRUE@pcre_jit_test_SOURCES = pcre_jit_test.c @WITH_JIT_TRUE@pcre_jit_test_LDADD = $(am__append_8) $(am__append_9) @WITH_PCRE8_TRUE@libpcreposix_la_SOURCES = \ @WITH_PCRE8_TRUE@ pcreposix.c @WITH_PCRE8_TRUE@libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS) @WITH_PCRE8_TRUE@libpcreposix_la_LIBADD = libpcre.la @WITH_PCRE_CPP_TRUE@libpcrecpp_la_SOURCES = \ @WITH_PCRE_CPP_TRUE@ pcrecpp_internal.h \ @WITH_PCRE_CPP_TRUE@ pcrecpp.cc \ @WITH_PCRE_CPP_TRUE@ pcre_scanner.cc \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece.cc @WITH_PCRE_CPP_TRUE@libpcrecpp_la_LDFLAGS = $(EXTRA_LIBPCRECPP_LDFLAGS) @WITH_PCRE_CPP_TRUE@libpcrecpp_la_LIBADD = libpcre.la @WITH_PCRE_CPP_TRUE@pcrecpp_unittest_SOURCES = pcrecpp_unittest.cc @WITH_PCRE_CPP_TRUE@pcrecpp_unittest_LDADD = libpcrecpp.la @WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_SOURCES = pcre_scanner_unittest.cc @WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_LDADD = libpcrecpp.la @WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc @WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_LDADD = libpcrecpp.la pcretest_SOURCES = pcretest.c $(am__append_14) $(am__append_16) pcretest_LDADD = $(LIBREADLINE) $(am__append_15) $(am__append_17) @WITH_PCRE8_TRUE@pcregrep_SOURCES = pcregrep.c @WITH_PCRE8_TRUE@pcregrep_LDADD = $(LIBZ) $(LIBBZ2) libpcre.la \ @WITH_PCRE8_TRUE@ libpcreposix.la # A PCRE user submitted the following addition, saying that it "will allow # anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a # nice DLL for Windows use". (It is used by the pcre.dll target.) DLL_OBJS = pcre_byte_order.o pcre_compile.o pcre_config.o \ pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \ pcre_globals.o pcre_jit_compile.o pcre_maketables.o \ pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \ pcre_study.o pcre_tables.o pcre_ucd.o \ pcre_valid_utf8.o pcre_version.o pcre_chartables.o \ pcre_xclass.o # We have .pc files for pkg-config users. pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpcre.pc libpcreposix.pc $(am__append_21) \ $(am__append_22) dist_man_MANS = \ doc/pcre.3 \ doc/pcre16.3 \ doc/pcre-config.1 \ doc/pcre_assign_jit_stack.3 \ doc/pcre_compile.3 \ doc/pcre_compile2.3 \ doc/pcre_config.3 \ doc/pcre_copy_named_substring.3 \ doc/pcre_copy_substring.3 \ doc/pcre_dfa_exec.3 \ doc/pcre_exec.3 \ doc/pcre_free_study.3 \ doc/pcre_free_substring.3 \ doc/pcre_free_substring_list.3 \ doc/pcre_fullinfo.3 \ doc/pcre_get_named_substring.3 \ doc/pcre_get_stringnumber.3 \ doc/pcre_get_stringtable_entries.3 \ doc/pcre_get_substring.3 \ doc/pcre_get_substring_list.3 \ doc/pcre_jit_stack_alloc.3 \ doc/pcre_jit_stack_free.3 \ doc/pcre_maketables.3 \ doc/pcre_pattern_to_host_byte_order.3 \ doc/pcre_refcount.3 \ doc/pcre_study.3 \ doc/pcre_utf16_to_host_byte_order.3 \ doc/pcre_version.3 \ doc/pcreapi.3 \ doc/pcrebuild.3 \ doc/pcrecallout.3 \ doc/pcrecompat.3 \ doc/pcregrep.1 \ doc/pcrejit.3 \ doc/pcrelimits.3 \ doc/pcrematching.3 \ doc/pcrepartial.3 \ doc/pcrepattern.3 \ doc/pcreperform.3 \ doc/pcreposix.3 \ doc/pcreprecompile.3 \ doc/pcresample.3 \ doc/pcrestack.3 \ doc/pcresyntax.3 \ doc/pcretest.1 \ doc/pcreunicode.3 pcrecpp_man = doc/pcrecpp.3 @WITH_PCRE_CPP_TRUE@man_MANS = $(pcrecpp_man) all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .cc .lo .o .obj am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 libpcre.pc: $(top_builddir)/config.status $(srcdir)/libpcre.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libpcre16.pc: $(top_builddir)/config.status $(srcdir)/libpcre16.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libpcreposix.pc: $(top_builddir)/config.status $(srcdir)/libpcreposix.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libpcrecpp.pc: $(top_builddir)/config.status $(srcdir)/libpcrecpp.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ pcre-config: $(top_builddir)/config.status $(srcdir)/pcre-config.in cd $(top_builddir) && $(SHELL) ./config.status $@ pcre.h: $(top_builddir)/config.status $(srcdir)/pcre.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ pcre_stringpiece.h: $(top_builddir)/config.status $(srcdir)/pcre_stringpiece.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ pcrecpparg.h: $(top_builddir)/config.status $(srcdir)/pcrecpparg.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libpcre.la: $(libpcre_la_OBJECTS) $(libpcre_la_DEPENDENCIES) $(AM_V_CCLD)$(libpcre_la_LINK) $(am_libpcre_la_rpath) $(libpcre_la_OBJECTS) $(libpcre_la_LIBADD) $(LIBS) libpcre16.la: $(libpcre16_la_OBJECTS) $(libpcre16_la_DEPENDENCIES) $(AM_V_CCLD)$(libpcre16_la_LINK) $(am_libpcre16_la_rpath) $(libpcre16_la_OBJECTS) $(libpcre16_la_LIBADD) $(LIBS) libpcrecpp.la: $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(libpcrecpp_la_LINK) $(am_libpcrecpp_la_rpath) $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_LIBADD) $(LIBS) libpcreposix.la: $(libpcreposix_la_OBJECTS) $(libpcreposix_la_DEPENDENCIES) $(AM_V_CCLD)$(libpcreposix_la_LINK) $(am_libpcreposix_la_rpath) $(libpcreposix_la_OBJECTS) $(libpcreposix_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) @rm -f dftables$(EXEEXT) $(AM_V_CCLD)$(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS) pcre_jit_test$(EXEEXT): $(pcre_jit_test_OBJECTS) $(pcre_jit_test_DEPENDENCIES) @rm -f pcre_jit_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pcre_jit_test_OBJECTS) $(pcre_jit_test_LDADD) $(LIBS) pcre_scanner_unittest$(EXEEXT): $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_DEPENDENCIES) @rm -f pcre_scanner_unittest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_LDADD) $(LIBS) pcre_stringpiece_unittest$(EXEEXT): $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_DEPENDENCIES) @rm -f pcre_stringpiece_unittest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_LDADD) $(LIBS) pcrecpp_unittest$(EXEEXT): $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_DEPENDENCIES) @rm -f pcrecpp_unittest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_LDADD) $(LIBS) pcregrep$(EXEEXT): $(pcregrep_OBJECTS) $(pcregrep_DEPENDENCIES) @rm -f pcregrep$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pcregrep_OBJECTS) $(pcregrep_LDADD) $(LIBS) pcretest$(EXEEXT): $(pcretest_OBJECTS) $(pcretest_DEPENDENCIES) @rm -f pcretest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pcretest_OBJECTS) $(pcretest_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dftables.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_byte_order.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_chartables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_compile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_dfa_exec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_exec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_fullinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_get.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_globals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_jit_compile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_maketables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_newline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_ord2utf16.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_printint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_refcount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_string_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_study.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_tables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_ucd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_utf16_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_valid_utf16.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_version.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_xclass.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_byte_order.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_chartables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_compile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_dfa_exec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_exec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_fullinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_get.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_globals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_jit_compile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_jit_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_maketables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_newline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_ord2utf8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_printint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_refcount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_scanner.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_scanner_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_string_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_stringpiece.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_stringpiece_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_study.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_tables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_ucd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_valid_utf8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_version.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_xclass.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcrecpp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcrecpp_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcregrep.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcreposix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcretest.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-man1: $(dist_man_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } install-man3: $(dist_man_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" @list=''; test -n "$(man3dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.3[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ done; } uninstall-man3: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man3dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.3[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man3dir)" && rm -f $$files; } install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-dist_docDATA: @$(NORMAL_UNINSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(docdir)" && rm -f $$files install-dist_htmlDATA: $(dist_html_DATA) @$(NORMAL_INSTALL) test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ done uninstall-dist_htmlDATA: @$(NORMAL_UNINSTALL) @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(htmldir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(htmldir)" && rm -f $$files install-htmlDATA: $(html_DATA) @$(NORMAL_INSTALL) test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" @list='$(html_DATA)'; test -n "$(htmldir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ done uninstall-htmlDATA: @$(NORMAL_UNINSTALL) @list='$(html_DATA)'; test -n "$(htmldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(htmldir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(htmldir)" && rm -f $$files install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(includedir)" && rm -f $$files install-nodist_includeHEADERS: $(nodist_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-nodist_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(includedir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ echo "$$grn$$dashes"; \ else \ echo "$$red$$dashes"; \ fi; \ echo "$$banner"; \ test -z "$$skipped" || echo "$$skipped"; \ test -z "$$report" || echo "$$report"; \ echo "$$dashes$$std"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__cd) '$(distuninstallcheck_dir)' \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ $(HEADERS) config.h install-binPROGRAMS: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_docDATA install-dist_htmlDATA \ install-htmlDATA install-includeHEADERS install-man \ install-nodist_includeHEADERS install-pkgconfigDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-binSCRIPTS \ install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-man3 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-dist_docDATA uninstall-dist_htmlDATA \ uninstall-htmlDATA uninstall-includeHEADERS \ uninstall-libLTLIBRARIES uninstall-man \ uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA uninstall-man: uninstall-man1 uninstall-man3 .MAKE: all check check-am install install-am install-data-am \ install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ clean clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstPROGRAMS ctags dist dist-all \ dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-compile \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-binSCRIPTS install-data \ install-data-am install-data-hook install-dist_docDATA \ install-dist_htmlDATA install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-htmlDATA \ install-includeHEADERS install-info install-info-am \ install-libLTLIBRARIES install-man install-man1 install-man3 \ install-nodist_includeHEADERS install-pdf install-pdf-am \ install-pkgconfigDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-binSCRIPTS uninstall-dist_docDATA \ uninstall-dist_htmlDATA uninstall-htmlDATA \ uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-man uninstall-man1 uninstall-man3 \ uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA pcre.h.generic: configure.ac rm -f $@ cp -p pcre.h $@ @WITH_REBUILD_CHARTABLES_TRUE@pcre_chartables.c: dftables$(EXEEXT) @WITH_REBUILD_CHARTABLES_TRUE@ ./dftables$(EXEEXT) $@ @WITH_REBUILD_CHARTABLES_FALSE@pcre_chartables.c: $(srcdir)/pcre_chartables.c.dist @WITH_REBUILD_CHARTABLES_FALSE@ rm -f $@ @WITH_REBUILD_CHARTABLES_FALSE@ $(LN_S) $(srcdir)/pcre_chartables.c.dist $@ # A compatibility line, the old build system worked with 'make test' test: check ; # A PCRE user submitted the following addition, saying that it "will allow # anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a # nice DLL for Windows use". pcre.dll: $(DLL_OBJS) $(CC) -shared -o pcre.dll -Wl,"--strip-all" -Wl,"--export-all-symbols" $(DLL_OBJS) # Arrange for the per-function man pages to have 16-bit names as well. install-data-hook: ln -sf pcre_assign_jit_stack.3 $(DESTDIR)$(man3dir)/pcre16_assign_jit_stack.3 ln -sf pcre_compile.3 $(DESTDIR)$(man3dir)/pcre16_compile.3 ln -sf pcre_compile2.3 $(DESTDIR)$(man3dir)/pcre16_compile2.3 ln -sf pcre_config.3 $(DESTDIR)$(man3dir)/pcre16_config.3 ln -sf pcre_copy_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_named_substring.3 ln -sf pcre_copy_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_substring.3 ln -sf pcre_dfa_exec.3 $(DESTDIR)$(man3dir)/pcre16_dfa_exec.3 ln -sf pcre_exec.3 $(DESTDIR)$(man3dir)/pcre16_exec.3 ln -sf pcre_free_study.3 $(DESTDIR)$(man3dir)/pcre16_free_study.3 ln -sf pcre_free_substring.3 $(DESTDIR)$(man3dir)/pcre16_free_substring.3 ln -sf pcre_free_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_free_substring_list.3 ln -sf pcre_fullinfo.3 $(DESTDIR)$(man3dir)/pcre16_fullinfo.3 ln -sf pcre_get_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_named_substring.3 ln -sf pcre_get_stringnumber.3 $(DESTDIR)$(man3dir)/pcre16_get_stringnumber.3 ln -sf pcre_get_stringtable_entries.3 $(DESTDIR)$(man3dir)/pcre16_get_stringtable_entries.3 ln -sf pcre_get_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_substring.3 ln -sf pcre_get_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_get_substring_list.3 ln -sf pcre_jit_stack_alloc.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_alloc.3 ln -sf pcre_jit_stack_free.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_free.3 ln -sf pcre_maketables.3 $(DESTDIR)$(man3dir)/pcre16_maketables.3 ln -sf pcre_pattern_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_pattern_to_host_byte_order.3 ln -sf pcre_refcount.3 $(DESTDIR)$(man3dir)/pcre16_refcount.3 ln -sf pcre_study.3 $(DESTDIR)$(man3dir)/pcre16_study.3 ln -sf pcre_utf16_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_utf16_to_host_byte_order.3 ln -sf pcre_version.3 $(DESTDIR)$(man3dir)/pcre16_version.3 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: pcre-8.31/NON-UNIX-USE0000644000222100022210000000034511767666334011120 00000000000000Compiling PCRE on non-Unix systems ---------------------------------- This has been renamed to better reflect its contents. Please see the file NON-AUTOTOOLS-BUILD for details of how to build PCRE without using autotools. #### pcre-8.31/pcre16_config.c0000644000222100022210000000417711676645217012124 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_config.c" /* End of pcre16_config.c */ pcre-8.31/pcre16_valid_utf16.c0000644000222100022210000001114211676645227012772 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains an internal function for validating UTF-16 character strings. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_internal.h" /************************************************* * Validate a UTF-16 string * *************************************************/ /* This function is called (optionally) at the start of compile or match, to check that a supposed UTF-16 string is actually valid. The early check means that subsequent code can assume it is dealing with a valid string. The check can be turned off for maximum performance, but the consequences of supplying an invalid string are then undefined. From release 8.21 more information about the details of the error are passed back in the returned value: PCRE_UTF16_ERR0 No error PCRE_UTF16_ERR1 Missing low surrogate at the end of the string PCRE_UTF16_ERR2 Invalid low surrogate PCRE_UTF16_ERR3 Isolated low surrogate PCRE_UTF16_ERR4 Not allowed character Arguments: string points to the string length length of string, or -1 if the string is zero-terminated errp pointer to an error position offset variable Returns: = 0 if the string is a valid UTF-16 string > 0 otherwise, setting the offset of the bad character */ int PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset) { #ifdef SUPPORT_UTF register PCRE_PUCHAR p; register pcre_uchar c; if (length < 0) { for (p = string; *p != 0; p++); length = p - string; } for (p = string; length-- > 0; p++) { c = *p; if ((c & 0xf800) != 0xd800) { /* Normal UTF-16 code point. Neither high nor low surrogate. */ /* This is probably a BOM from a different byte-order. Regardless, the string is rejected. */ if (c == 0xfffe) { *erroroffset = p - string; return PCRE_UTF16_ERR4; } } else if ((c & 0x0400) == 0) { /* High surrogate. */ /* Must be a followed by a low surrogate. */ if (length == 0) { *erroroffset = p - string; return PCRE_UTF16_ERR1; } p++; length--; if ((*p & 0xfc00) != 0xdc00) { *erroroffset = p - string; return PCRE_UTF16_ERR2; } } else { /* Isolated low surrogate. Always an error. */ *erroroffset = p - string; return PCRE_UTF16_ERR3; } } #else /* SUPPORT_UTF */ (void)(string); /* Keep picky compilers happy */ (void)(length); #endif /* SUPPORT_UTF */ return PCRE_UTF16_ERR0; /* This indicates success */ } /* End of pcre16_valid_utf16.c */ pcre-8.31/pcre_xclass.c0000644000222100022210000001370511676645226012002 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains an internal function that is used to match an extended class. It is used by both pcre_exec() and pcre_def_exec(). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Match character against an XCLASS * *************************************************/ /* This function is called to match a character against an extended class that might contain values > 255 and/or Unicode properties. Arguments: c the character data points to the flag byte of the XCLASS data Returns: TRUE if character matches, else FALSE */ BOOL PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf) { int t; BOOL negated = (*data & XCL_NOT) != 0; (void)utf; #ifdef COMPILE_PCRE8 /* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */ utf = TRUE; #endif /* Character values < 256 are matched against a bitmap, if one is present. If not, we still carry on, because there may be ranges that start below 256 in the additional data. */ if (c < 256) { if ((*data & XCL_MAP) != 0 && (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0) return !negated; /* char found */ } /* First skip the bit map if present. Then match against the list of Unicode properties or large chars or ranges that end with a large char. We won't ever encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */ if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar); while ((t = *data++) != XCL_END) { int x, y; if (t == XCL_SINGLE) { #ifdef SUPPORT_UTF if (utf) { GETCHARINC(x, data); /* macro generates multiple statements */ } else #endif x = *data++; if (c == x) return !negated; } else if (t == XCL_RANGE) { #ifdef SUPPORT_UTF if (utf) { GETCHARINC(x, data); /* macro generates multiple statements */ GETCHARINC(y, data); /* macro generates multiple statements */ } else #endif { x = *data++; y = *data++; } if (c >= x && c <= y) return !negated; } #ifdef SUPPORT_UCP else /* XCL_PROP & XCL_NOTPROP */ { const ucd_record *prop = GET_UCD(c); switch(*data) { case PT_ANY: if (t == XCL_PROP) return !negated; break; case PT_LAMP: if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated; break; case PT_GC: if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP)) return !negated; break; case PT_PC: if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated; break; case PT_SC: if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated; break; case PT_ALNUM: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP)) return !negated; break; case PT_SPACE: /* Perl space */ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP)) return !negated; break; case PT_PXSPACE: /* POSIX space */ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP)) return !negated; break; case PT_WORD: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == (t == XCL_PROP)) return !negated; break; /* This should never occur, but compilers may mutter if there is no default. */ default: return FALSE; } data += 2; } #endif /* SUPPORT_UCP */ } return negated; /* char did not match */ } /* End of pcre_xclass.c */ pcre-8.31/RunTest.bat0000644000222100022210000003310211705300547011400 00000000000000@echo off @rem This file must use CRLF linebreaks to function properly @rem and requires both pcretest and pcregrep @rem This file was originally contributed by Ralf Junker, and touched up by @rem Daniel Richard G. Tests 10-12 added by Philip H. @rem Philip H also changed test 3 to use "wintest" files. @rem @rem Updated by Tom Fortmann to support explicit test numbers on the command line. @rem Added argument validation and added error reporting. @rem @rem MS Windows batch file to run pcretest on testfiles with the correct @rem options. @rem @rem Sheri Pierce added logic to skip feature dependent tests @rem tests 4 5 9 15 and 18 require utf support @rem tests 6 7 10 16 and 19 require ucp support @rem 11 requires ucp and link size 2 @rem 12 requires presense of jit support @rem 13 requires absence of jit support @rem Sheri P also added override tests for study and jit testing @rem Zoltan Herczeg added libpcre16 support setlocal enabledelayedexpansion if [%srcdir%]==[] ( if exist testdata\ set srcdir=.) if [%srcdir%]==[] ( if exist ..\testdata\ set srcdir=..) if [%srcdir%]==[] ( if exist ..\..\testdata\ set srcdir=..\..) if NOT exist "%srcdir%\testdata\" ( Error: echo distribution testdata folder not found! call :conferror exit /b 1 goto :eof ) if "%pcretest%"=="" set pcretest=.\pcretest.exe echo source dir is %srcdir% echo pcretest=%pcretest% if NOT exist "%pcretest%" ( echo Error: "%pcretest%" not found! echo. call :conferror exit /b 1 ) "%pcretest%" -C linksize >NUL set link_size=%ERRORLEVEL% "%pcretest%" -C pcre8 >NUL set support8=%ERRORLEVEL% "%pcretest%" -C pcre16 >NUL set support16=%ERRORLEVEL% "%pcretest%" -C utf >NUL set utf=%ERRORLEVEL% "%pcretest%" -C ucp >NUL set ucp=%ERRORLEVEL% "%pcretest%" -C jit >NUL set jit=%ERRORLEVEL% if %support8% EQU 1 ( if not exist testout8 md testout8 if not exist testoutstudy8 md testoutstudy8 if not exist testoutjit8 md testoutjit8 ) if %support16% EQU 1 ( if not exist testout16 md testout16 if not exist testoutstudy16 md testoutstudy16 if not exist testoutjit16 md testoutjit16 ) set do1=no set do2=no set do3=no set do4=no set do5=no set do6=no set do7=no set do8=no set do9=no set do10=no set do11=no set do12=no set do13=no set do14=no set do15=no set do16=no set do17=no set do18=no set do19=no set do20=no set all=yes for %%a in (%*) do ( set valid=no for %%v in (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) do if %%v == %%a set valid=yes if "!valid!" == "yes" ( set do%%a=yes set all=no ) else ( echo Invalid test number - %%a! echo Usage %0 [ test_number ] ... echo Where test_number is one or more optional test numbers 1 through 20, default is all tests. exit /b 1 ) ) set failed="no" if "%all%" == "yes" ( set do1=yes set do2=yes set do3=yes set do4=yes set do5=yes set do6=yes set do7=yes set do8=yes set do9=yes set do10=yes set do11=yes set do12=yes set do13=yes set do14=yes set do15=yes set do16=yes set do17=yes set do18=yes set do19=yes set do20=yes ) @echo RunTest.bat's pcretest output is written to newly created subfolders named @echo testout, testoutstudy and testoutjit. @echo. set mode= set bits=8 :nextMode if "%mode%" == "" ( if %support8% EQU 0 goto modeSkip echo. echo ---- Testing 8-bit library ---- echo. ) else ( if %support16% EQU 0 goto modeSkip echo. echo ---- Testing 16-bit library ---- echo. ) if "%do1%" == "yes" call :do1 if "%do2%" == "yes" call :do2 if "%do3%" == "yes" call :do3 if "%do4%" == "yes" call :do4 if "%do5%" == "yes" call :do5 if "%do6%" == "yes" call :do6 if "%do7%" == "yes" call :do7 if "%do8%" == "yes" call :do8 if "%do9%" == "yes" call :do9 if "%do10%" == "yes" call :do10 if "%do11%" == "yes" call :do11 if "%do12%" == "yes" call :do12 if "%do13%" == "yes" call :do13 if "%do14%" == "yes" call :do14 if "%do15%" == "yes" call :do15 if "%do16%" == "yes" call :do16 if "%do17%" == "yes" call :do17 if "%do18%" == "yes" call :do18 if "%do19%" == "yes" call :do19 if "%do20%" == "yes" call :do20 :modeSkip if "%mode%" == "" ( set mode=-16 set bits=16 goto nextMode ) if %failed% == "yes" ( echo In above output, one or more of the various tests failed! exit /b 1 ) echo All OK goto :eof :runsub @rem Function to execute pcretest and compare the output @rem Arguments are as follows: @rem @rem 1 = test number @rem 2 = outputdir @rem 3 = test name use double quotes @rem 4 - 9 = pcretest options if [%1] == [] ( echo Missing test number argument! exit /b 1 ) if [%2] == [] ( echo Missing outputdir! exit /b 1 ) if [%3] == [] ( echo Missing test name argument! exit /b 1 ) set testinput=testinput%1 set testoutput=testoutput%1 if exist %srcdir%\testdata\win%testinput% ( set testinput=wintestinput%1 set testoutput=wintestoutput%1 ) echo Test %1: %3 "%pcretest%" %mode% %4 %5 %6 %7 %8 %9 "%srcdir%\testdata\%testinput%">%2%bits%\%testoutput% if errorlevel 1 ( echo. failed executing command-line: echo. "%pcretest%" %mode% %4 %5 %6 %7 %8 %9 "%srcdir%\testdata\%testinput%"^>%2%bits%\%testoutput% set failed="yes" goto :eof ) if [%1]==[11] ( fc /n "%srcdir%\testdata\%testoutput%-%bits%" "%2%bits%\%testoutput%">NUL ) else ( fc /n "%srcdir%\testdata\%testoutput%" "%2%bits%\%testoutput%">NUL ) if errorlevel 1 ( echo. failed comparison: fc /n "%srcdir%\testdata\%testoutput%" "%2%bits%\%testoutput%" if [%1]==[2] ( echo. echo ** Test 2 requires a lot of stack. PCRE can be configured to echo ** use heap for recursion. Otherwise, to pass Test 2 echo ** you generally need to allocate 8 mb stack to PCRE. echo ** See the 'pcrestack' page for a discussion of PCRE's echo ** stack usage. echo. ) if [%1]==[3] ( echo. echo ** Test 3 failure usually means french locale is not echo ** available on the system, rather than a bug or problem with PCRE. echo. goto :eof ) set failed="yes" goto :eof ) echo. Passed. goto :eof :do1 call :runsub 1 testout "Main functionality - Compatible with Perl 5.8 and above" -q call :runsub 1 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 1 testoutjit "Test with JIT Override" -q -s+ goto :eof :do2 call :runsub 2 testout "API, errors, internals, and non-Perl stuff (not UTF-8)" -q call :runsub 2 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 2 testoutjit "Test with JIT Override" -q -s+ goto :eof :do3 call :runsub 3 testout "Locale-specific features" -q call :runsub 3 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 3 testoutjit "Test with JIT Override" -q -s+ goto :eof :do4 if %utf% EQU 0 ( echo Test 4 Skipped due to absence of UTF-%bits% support. goto :eof ) call :runsub 4 testout "UTF-%bits% support - Compatible with Perl 5.8 and above" -q call :runsub 4 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 4 testoutjit "Test with JIT Override" -q -s+ goto :eof :do5 if %utf% EQU 0 ( echo Test 5 Skipped due to absence of UTF-%bits% support. goto :eof ) call :runsub 5 testout "API, internals, and non-Perl stuff for UTF-%bits% support" -q call :runsub 5 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 5 testoutjit "Test with JIT Override" -q -s+ goto :eof :do6 if %ucp% EQU 0 ( echo Test 6 Skipped due to absence of Unicode property support. goto :eof ) call :runsub 6 testout "Unicode property support (Compatible with Perl >= 5.10)" -q call :runsub 6 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 6 testoutjit "Test with JIT Override" -q -s+ goto :eof :do7 if %ucp% EQU 0 ( echo Test 7 Skipped due to absence of Unicode property support. goto :eof ) call :runsub 7 testout "API, internals, and non-Perl stuff for Unicode property support" -q call :runsub 7 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 7 testoutjit "Test with JIT Override" -q -s+ goto :eof :do8 call :runsub 8 testout "DFA matching main functionality" -q -dfa call :runsub 8 testoutstudy "Test with Study Override" -q -dfa -s goto :eof :do9 if %utf% EQU 0 ( echo Test 9 Skipped due to absence of UTF-%bits% support. goto :eof ) call :runsub 9 testout "DFA matching with UTF-%bits%" -q -dfa call :runsub 9 testoutstudy "Test with Study Override" -q -dfa -s goto :eof :do10 if %ucp% EQU 0 ( echo Test 10 Skipped due to absence of Unicode property support. goto :eof ) call :runsub 10 testout "DFA matching with Unicode properties" -q -dfa call :runsub 10 testoutstudy "Test with Study Override" -q -dfa -s goto :eof :do11 if NOT %link_size% EQU 2 ( echo Test 11 Skipped because link size is not 2. goto :eof ) if %ucp% EQU 0 ( echo Test 11 Skipped due to absence of Unicode property support. goto :eof ) call :runsub 11 testout "Internal offsets and code size tests" -q call :runsub 11 testoutstudy "Test with Study Override" -q -s goto :eof :do12 if %jit% EQU 0 ( echo Test 12 Skipped due to absence of JIT support. goto :eof ) call :runsub 12 testout "JIT-specific features - have JIT" -q goto :eof :do13 if %jit% EQU 1 ( echo Test 13 Skipped due to presence of JIT support. goto :eof ) call :runsub 13 testout "JIT-specific features - no JIT" -q goto :eof :do14 if NOT %bits% EQU 8 ( echo Test 14 Skipped when running 16-bit tests. goto :eof ) copy /Y "%srcdir%\testdata\saved16" testsaved16 call :runsub 14 testout "Specials for the basic 8-bit library" -q call :runsub 14 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 14 testoutjit "Test with JIT Override" -q -s+ goto :eof :do15 if NOT %bits% EQU 8 ( echo Test 15 Skipped when running 16-bit tests. goto :eof ) if %utf% EQU 0 ( echo Test 15 Skipped due to absence of UTF-8 support. goto :eof ) call :runsub 15 testout "Specials for the 8-bit library with UTF-8 support" -q call :runsub 15 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 15 testoutjit "Test with JIT Override" -q -s+ goto :eof :do16 if NOT %bits% EQU 8 ( echo Test 16 Skipped when running 16-bit tests. goto :eof ) if %ucp% EQU 0 ( echo Test 16 Skipped due to absence of Unicode property support. goto :eof ) call :runsub 16 testout "Specials for the 8-bit library with Unicode propery support" -q call :runsub 16 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 16 testoutjit "Test with JIT Override" -q -s+ goto :eof :do17 if NOT %bits% EQU 16 ( echo Test 17 Skipped when running 8-bit tests. goto :eof ) copy /Y "%srcdir%\testdata\saved8" testsaved8 copy /Y "%srcdir%\testdata\saved16LE-1" testsaved16LE-1 copy /Y "%srcdir%\testdata\saved16BE-1" testsaved16BE-1 call :runsub 17 testout "Specials for the basic 8-bit library" -q call :runsub 17 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 17 testoutjit "Test with JIT Override" -q -s+ goto :eof :do18 if NOT %bits% EQU 16 ( echo Test 18 Skipped when running 8-bit tests. goto :eof ) if %utf% EQU 0 ( echo Test 18 Skipped due to absence of UTF-8 support. goto :eof ) copy /Y "%srcdir%\testdata\saved16LE-2" testsaved16LE-2 copy /Y "%srcdir%\testdata\saved16BE-2" testsaved16BE-2 call :runsub 18 testout "Specials for the basic 8-bit library" -q call :runsub 18 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 18 testoutjit "Test with JIT Override" -q -s+ goto :eof :do19 if NOT %bits% EQU 16 ( echo Test 19 Skipped when running 8-bit tests. goto :eof ) if %ucp% EQU 0 ( echo Test 19 Skipped due to absence of Unicode property support. goto :eof ) call :runsub 19 testout "Specials for the basic 8-bit library" -q call :runsub 19 testoutstudy "Test with Study Override" -q -s if %jit% EQU 1 call :runsub 19 testoutjit "Test with JIT Override" -q -s+ goto :eof :do20 if NOT %bits% EQU 16 ( echo Test 20 Skipped when running 8-bit tests. goto :eof ) call :runsub 20 testout "DFA specials for the basic 16-bit library" -q call :runsub 20 testoutstudy "Test with Study Override" -q -s goto :eof :conferror @echo. @echo Either your build is incomplete or you have a configuration error. @echo. @echo If configured with cmake and executed via "make test" or the MSVC "RUN_TESTS" @echo project, pcre_test.bat defines variables and automatically calls RunTest.bat. @echo For manual testing of all available features, after configuring with cmake @echo and building, you can run the built pcre_test.bat. For best results with @echo cmake builds and tests avoid directories with full path names that include @echo spaces for source or build. @echo. @echo Otherwise, if the build dir is in a subdir of the source dir, testdata needed @echo for input and verification should be found automatically when (from the @echo location of the the built exes) you call RunTest.bat. By default RunTest.bat @echo runs all tests compatible with the linked pcre library but it can be given @echo a test number as an argument. @echo. @echo If the build dir is not under the source dir you can either copy your exes @echo to the source folder or copy RunTest.bat and the testdata folder to the @echo location of your built exes and then run RunTest.bat. @echo. goto :eof pcre-8.31/pcre_study.c0000644000222100022210000012344511775523430011650 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_study(), along with local supporting functions. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" #define SET_BIT(c) start_bits[c/8] |= (1 << (c&7)) /* Returns from set_start_bits() */ enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; /************************************************* * Find the minimum subject length for a group * *************************************************/ /* Scan a parenthesized group and compute the minimum length of subject that is needed to match it. This is a lower bound; it does not mean there is a string of that length that matches. In UTF8 mode, the result is in characters rather than bytes. Arguments: code pointer to start of group (the bracket) startcode pointer to start of the whole pattern options the compiling options int RECURSE depth Returns: the minimum length -1 if \C in UTF-8 mode or (*ACCEPT) was encountered -2 internal error (missing capturing bracket) -3 internal error (opcode not listed) */ static int find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options, int recurse_depth) { int length = -1; /* PCRE_UTF16 has the same value as PCRE_UTF8. */ BOOL utf = (options & PCRE_UTF8) != 0; BOOL had_recurse = FALSE; register int branchlength = 0; register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE; if (*code == OP_CBRA || *code == OP_SCBRA || *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ for (;;) { int d, min; pcre_uchar *cs, *ce; register int op = *cc; switch (op) { case OP_COND: case OP_SCOND: /* If there is only one branch in a condition, the implied branch has zero length, so we don't add anything. This covers the DEFINE "condition" automatically. */ cs = cc + GET(cc, 1); if (*cs != OP_ALT) { cc = cs + 1 + LINK_SIZE; break; } /* Otherwise we can fall through and treat it the same as any other subpattern. */ case OP_CBRA: case OP_SCBRA: case OP_BRA: case OP_SBRA: case OP_CBRAPOS: case OP_SCBRAPOS: case OP_BRAPOS: case OP_SBRAPOS: case OP_ONCE: case OP_ONCE_NC: d = find_minlength(cc, startcode, options, recurse_depth); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; /* ACCEPT makes things far too complicated; we have to give up. */ case OP_ACCEPT: case OP_ASSERT_ACCEPT: return -1; /* Reached end of a branch; if it's a ket it is the end of a nested call. If it's ALT it is an alternation in a nested call. If it is END it's the end of the outer call. All can be handled by the same code. If an ACCEPT was previously encountered, use the length that was in force at that time, and pass back the shortest ACCEPT length. */ case OP_ALT: case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_KETRPOS: case OP_END: if (length < 0 || (!had_recurse && branchlength < length)) length = branchlength; if (op != OP_ALT) return length; cc += 1 + LINK_SIZE; branchlength = 0; had_recurse = FALSE; break; /* Skip over assertive subpatterns */ case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do cc += GET(cc, 1); while (*cc == OP_ALT); /* Fall through */ /* Skip over things that don't match chars */ case OP_REVERSE: case OP_CREF: case OP_NCREF: case OP_RREF: case OP_NRREF: case OP_DEF: case OP_CALLOUT: case OP_SOD: case OP_SOM: case OP_EOD: case OP_EODN: case OP_CIRC: case OP_CIRCM: case OP_DOLL: case OP_DOLLM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: cc += PRIV(OP_lengths)[*cc]; break; /* Skip over a subpattern that has a {0} or {0,x} quantifier */ case OP_BRAZERO: case OP_BRAMINZERO: case OP_BRAPOSZERO: case OP_SKIPZERO: cc += PRIV(OP_lengths)[*cc]; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; /* Handle literal characters and + repetitions */ case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: case OP_PLUS: case OP_PLUSI: case OP_MINPLUS: case OP_MINPLUSI: case OP_POSPLUS: case OP_POSPLUSI: case OP_NOTPLUS: case OP_NOTPLUSI: case OP_NOTMINPLUS: case OP_NOTMINPLUSI: case OP_NOTPOSPLUS: case OP_NOTPOSPLUSI: branchlength++; cc += 2; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: branchlength++; cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2; break; /* Handle exact repetitions. The count is already in characters, but we need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: case OP_EXACTI: case OP_NOTEXACT: case OP_NOTEXACTI: branchlength += GET2(cc,1); cc += 2 + IMM2_SIZE; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); break; /* Handle single-char non-literal matchers */ case OP_PROP: case OP_NOTPROP: cc += 2; /* Fall through */ case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: case OP_ALLANY: case OP_EXTUNI: case OP_HSPACE: case OP_NOT_HSPACE: case OP_VSPACE: case OP_NOT_VSPACE: branchlength++; cc++; break; /* "Any newline" might match two characters, but it also might match just one. */ case OP_ANYNL: branchlength += 1; cc++; break; /* The single-byte matcher means we can't proceed in UTF-8 mode. (In non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever appear, but leave the code, just in case.) */ case OP_ANYBYTE: #ifdef SUPPORT_UTF if (utf) return -1; #endif branchlength++; cc++; break; /* For repeated character types, we have to test for \p and \P, which have an extra two bytes of parameters. */ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSSTAR: case OP_TYPEPOSQUERY: if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2; cc += PRIV(OP_lengths)[op]; break; case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; cc += PRIV(OP_lengths)[op]; break; /* Check a class for variable quantification */ #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: cc += PRIV(OP_lengths)[OP_CLASS]; switch (*cc) { case OP_CRPLUS: case OP_CRMINPLUS: branchlength++; /* Fall through */ case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: cc++; break; case OP_CRRANGE: case OP_CRMINRANGE: branchlength += GET2(cc,1); cc += 1 + 2 * IMM2_SIZE; break; default: branchlength++; break; } break; /* Backreferences and subroutine calls are treated in the same way: we find the minimum length for the subpattern. A recursion, however, causes an a flag to be set that causes the length of this branch to be ignored. The logic is that a recursion can only make sense if there is another alternation that stops the recursing. That will provide the minimum length (when no recursion happens). A backreference within the group that it is referencing behaves in the same way. If PCRE_JAVASCRIPT_COMPAT is set, a backreference to an unset bracket matches an empty string (by default it causes a matching failure), so in that case we must set the minimum length to zero. */ case OP_REF: case OP_REFI: if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) { ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1)); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); if (cc > cs && cc < ce) { d = 0; had_recurse = TRUE; } else { d = find_minlength(cs, startcode, options, recurse_depth); } } else d = 0; cc += 1 + IMM2_SIZE; /* Handle repeated back references */ switch (*cc) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: min = 0; cc++; break; case OP_CRPLUS: case OP_CRMINPLUS: min = 1; cc++; break; case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(cc, 1); cc += 1 + 2 * IMM2_SIZE; break; default: min = 1; break; } branchlength += min * d; break; /* We can easily detect direct recursion, but not mutual recursion. This is caught by a recursion depth count. */ case OP_RECURSE: cs = ce = (pcre_uchar *)startcode + GET(cc, 1); do ce += GET(ce, 1); while (*ce == OP_ALT); if ((cc > cs && cc < ce) || recurse_depth > 10) had_recurse = TRUE; else { branchlength += find_minlength(cs, startcode, options, recurse_depth + 1); } cc += 1 + LINK_SIZE; break; /* Anything else does not or need not match a character. We can get the item's length from the table, but for those that can match zero occurrences of a character, we must take special action for UTF-8 characters. As it happens, the "NOT" versions of these opcodes are used at present only for ASCII characters, so they could be omitted from this list. However, in future that may change, so we include them here so as not to leave a gotcha for a future maintainer. */ case OP_UPTO: case OP_UPTOI: case OP_NOTUPTO: case OP_NOTUPTOI: case OP_MINUPTO: case OP_MINUPTOI: case OP_NOTMINUPTO: case OP_NOTMINUPTOI: case OP_POSUPTO: case OP_POSUPTOI: case OP_NOTPOSUPTO: case OP_NOTPOSUPTOI: case OP_STAR: case OP_STARI: case OP_NOTSTAR: case OP_NOTSTARI: case OP_MINSTAR: case OP_MINSTARI: case OP_NOTMINSTAR: case OP_NOTMINSTARI: case OP_POSSTAR: case OP_POSSTARI: case OP_NOTPOSSTAR: case OP_NOTPOSSTARI: case OP_QUERY: case OP_QUERYI: case OP_NOTQUERY: case OP_NOTQUERYI: case OP_MINQUERY: case OP_MINQUERYI: case OP_NOTMINQUERY: case OP_NOTMINQUERYI: case OP_POSQUERY: case OP_POSQUERYI: case OP_NOTPOSQUERY: case OP_NOTPOSQUERYI: cc += PRIV(OP_lengths)[op]; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; /* Skip these, but we need to add in the name length. */ case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: cc += PRIV(OP_lengths)[op] + cc[1]; break; /* The remaining opcodes are just skipped over. */ case OP_CLOSE: case OP_COMMIT: case OP_FAIL: case OP_PRUNE: case OP_SET_SOM: case OP_SKIP: case OP_THEN: cc += PRIV(OP_lengths)[op]; break; /* This should not occur: we list all opcodes explicitly so that when new ones get added they are properly considered. */ default: return -3; } } /* Control never gets here */ } /************************************************* * Set a bit and maybe its alternate case * *************************************************/ /* Given a character, set its first byte's bit in the table, and also the corresponding bit for the other version of a letter if we are caseless. In UTF-8 mode, for characters greater than 127, we can only do the caseless thing when Unicode property support is available. Arguments: start_bits points to the bit map p points to the character caseless the caseless flag cd the block with char table pointers utf TRUE for UTF-8 / UTF-16 mode Returns: pointer after the character */ static const pcre_uchar * set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless, compile_data *cd, BOOL utf) { unsigned int c = *p; #ifdef COMPILE_PCRE8 SET_BIT(c); #ifdef SUPPORT_UTF if (utf && c > 127) { GETCHARINC(c, p); #ifdef SUPPORT_UCP if (caseless) { pcre_uchar buff[6]; c = UCD_OTHERCASE(c); (void)PRIV(ord2utf)(c, buff); SET_BIT(buff[0]); } #endif return p; } #endif /* Not UTF-8 mode, or character is less than 127. */ if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); return p + 1; #endif #ifdef COMPILE_PCRE16 if (c > 0xff) { c = 0xff; caseless = FALSE; } SET_BIT(c); #ifdef SUPPORT_UTF if (utf && c > 127) { GETCHARINC(c, p); #ifdef SUPPORT_UCP if (caseless) { c = UCD_OTHERCASE(c); if (c > 0xff) c = 0xff; SET_BIT(c); } #endif return p; } #endif if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); return p + 1; #endif } /************************************************* * Set bits for a positive character type * *************************************************/ /* This function sets starting bits for a character type. In UTF-8 mode, we can only do a direct setting for bytes less than 128, as otherwise there can be confusion with bytes in the middle of UTF-8 characters. In a "traditional" environment, the tables will only recognize ASCII characters anyway, but in at least one Windows environment, some higher bytes bits were set in the tables. So we deal with that case by considering the UTF-8 encoding. Arguments: start_bits the starting bitmap cbit type the type of character wanted table_limit 32 for non-UTF-8; 16 for UTF-8 cd the block with char table pointers Returns: nothing */ static void set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type]; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit == 32) return; for (c = 128; c < 256; c++) { if ((cd->cbits[c/8] & (1 << (c&7))) != 0) { pcre_uchar buff[6]; (void)PRIV(ord2utf)(c, buff); SET_BIT(buff[0]); } } #endif } /************************************************* * Set bits for a negative character type * *************************************************/ /* This function sets starting bits for a negative character type such as \D. In UTF-8 mode, we can only do a direct setting for bytes less than 128, as otherwise there can be confusion with bytes in the middle of UTF-8 characters. Unlike in the positive case, where we can set appropriate starting bits for specific high-valued UTF-8 characters, in this case we have to set the bits for all high-valued characters. The lowest is 0xc2, but we overkill by starting at 0xc0 (192) for simplicity. Arguments: start_bits the starting bitmap cbit type the type of character wanted table_limit 32 for non-UTF-8; 16 for UTF-8 cd the block with char table pointers Returns: nothing */ static void set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type]; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff; #endif } /************************************************* * Create bitmap of starting bytes * *************************************************/ /* This function scans a compiled unanchored expression recursively and attempts to build a bitmap of the set of possible starting bytes. As time goes by, we may be able to get more clever at doing this. The SSB_CONTINUE return is useful for parenthesized groups in patterns such as (a*)b where the group provides some optional starting bytes but scanning must continue at the outer level to find at least one mandatory byte. At the outermost level, this function fails unless the result is SSB_DONE. Arguments: code points to an expression start_bits points to a 32-byte table, initialized to 0 utf TRUE if in UTF-8 / UTF-16 mode cd the block with char table pointers Returns: SSB_FAIL => Failed to find any starting bytes SSB_DONE => Found mandatory starting bytes SSB_CONTINUE => Found optional starting bytes SSB_UNKNOWN => Hit an unrecognized opcode */ static int set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf, compile_data *cd) { register int c; int yield = SSB_DONE; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 int table_limit = utf? 16:32; #else int table_limit = 32; #endif #if 0 /* ========================================================================= */ /* The following comment and code was inserted in January 1999. In May 2006, when it was observed to cause compiler warnings about unused values, I took it out again. If anybody is still using OS/2, they will have to put it back manually. */ /* This next statement and the later reference to dummy are here in order to trick the optimizer of the IBM C compiler for OS/2 into generating correct code. Apparently IBM isn't going to fix the problem, and we would rather not disable optimization (in this module it actually makes a big difference, and the pcre module can use all the optimization it can get). */ volatile int dummy; /* ========================================================================= */ #endif do { BOOL try_next = TRUE; const pcre_uchar *tcode = code + 1 + LINK_SIZE; if (*code == OP_CBRA || *code == OP_SCBRA || *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE; while (try_next) /* Loop for items in this branch */ { int rc; switch(*tcode) { /* If we reach something we don't understand, it means a new opcode has been created that hasn't been added to this code. Hopefully this problem will be discovered during testing. */ default: return SSB_UNKNOWN; /* Fail for a valid opcode that implies no starting bits. */ case OP_ACCEPT: case OP_ASSERT_ACCEPT: case OP_ALLANY: case OP_ANY: case OP_ANYBYTE: case OP_CIRC: case OP_CIRCM: case OP_CLOSE: case OP_COMMIT: case OP_COND: case OP_CREF: case OP_DEF: case OP_DOLL: case OP_DOLLM: case OP_END: case OP_EOD: case OP_EODN: case OP_EXTUNI: case OP_FAIL: case OP_MARK: case OP_NCREF: case OP_NOT: case OP_NOTEXACT: case OP_NOTEXACTI: case OP_NOTI: case OP_NOTMINPLUS: case OP_NOTMINPLUSI: case OP_NOTMINQUERY: case OP_NOTMINQUERYI: case OP_NOTMINSTAR: case OP_NOTMINSTARI: case OP_NOTMINUPTO: case OP_NOTMINUPTOI: case OP_NOTPLUS: case OP_NOTPLUSI: case OP_NOTPOSPLUS: case OP_NOTPOSPLUSI: case OP_NOTPOSQUERY: case OP_NOTPOSQUERYI: case OP_NOTPOSSTAR: case OP_NOTPOSSTARI: case OP_NOTPOSUPTO: case OP_NOTPOSUPTOI: case OP_NOTPROP: case OP_NOTQUERY: case OP_NOTQUERYI: case OP_NOTSTAR: case OP_NOTSTARI: case OP_NOTUPTO: case OP_NOTUPTOI: case OP_NOT_HSPACE: case OP_NOT_VSPACE: case OP_NRREF: case OP_PROP: case OP_PRUNE: case OP_PRUNE_ARG: case OP_RECURSE: case OP_REF: case OP_REFI: case OP_REVERSE: case OP_RREF: case OP_SCOND: case OP_SET_SOM: case OP_SKIP: case OP_SKIP_ARG: case OP_SOD: case OP_SOM: case OP_THEN: case OP_THEN_ARG: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: #endif return SSB_FAIL; /* We can ignore word boundary tests. */ case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: tcode++; break; /* If we hit a bracket or a positive lookahead assertion, recurse to set bits from within the subpattern. If it can't find anything, we have to give up. If it finds some mandatory character(s), we are done for this branch. Otherwise, carry on scanning after the subpattern. */ case OP_BRA: case OP_SBRA: case OP_CBRA: case OP_SCBRA: case OP_BRAPOS: case OP_SBRAPOS: case OP_CBRAPOS: case OP_SCBRAPOS: case OP_ONCE: case OP_ONCE_NC: case OP_ASSERT: rc = set_start_bits(tcode, start_bits, utf, cd); if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; if (rc == SSB_DONE) try_next = FALSE; else { do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; } break; /* If we hit ALT or KET, it means we haven't found anything mandatory in this branch, though we might have found something optional. For ALT, we continue with the next alternative, but we have to arrange that the final result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET, return SSB_CONTINUE: if this is the top level, that indicates failure, but after a nested subpattern, it causes scanning to continue. */ case OP_ALT: yield = SSB_CONTINUE; try_next = FALSE; break; case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_KETRPOS: return SSB_CONTINUE; /* Skip over callout */ case OP_CALLOUT: tcode += 2 + 2*LINK_SIZE; break; /* Skip over lookbehind and negative lookahead assertions */ case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; /* BRAZERO does the bracket, but carries on. */ case OP_BRAZERO: case OP_BRAMINZERO: case OP_BRAPOSZERO: rc = set_start_bits(++tcode, start_bits, utf, cd); if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; /* ========================================================================= 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; /* SKIPZERO skips the bracket. */ case OP_SKIPZERO: tcode++; do tcode += GET(tcode,1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; /* Single-char * or ? sets the bit and tries the next item */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf); break; case OP_STARI: case OP_MINSTARI: case OP_POSSTARI: case OP_QUERYI: case OP_MINQUERYI: case OP_POSQUERYI: tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf); break; /* Single-char upto sets the bit and tries the next */ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf); break; case OP_UPTOI: case OP_MINUPTOI: case OP_POSUPTOI: tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf); break; /* At least one single char sets the bit and stops */ case OP_EXACT: tcode += IMM2_SIZE; /* Fall through */ case OP_CHAR: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf); try_next = FALSE; break; case OP_EXACTI: tcode += IMM2_SIZE; /* Fall through */ case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: case OP_POSPLUSI: (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf); try_next = FALSE; break; /* Special spacing and line-terminating items. These recognize specific lists of characters. The difference between VSPACE and ANYNL is that the latter can match the two-character CRLF sequence, but that is not relevant for finding the first character, so their code here is identical. */ case OP_HSPACE: SET_BIT(0x09); SET_BIT(0x20); #ifdef SUPPORT_UTF if (utf) { #ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+00A0 */ SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ #endif #ifdef COMPILE_PCRE16 SET_BIT(0xA0); SET_BIT(0xFF); /* For characters > 255 */ #endif } else #endif /* SUPPORT_UTF */ { SET_BIT(0xA0); #ifdef COMPILE_PCRE16 SET_BIT(0xFF); /* For characters > 255 */ #endif } try_next = FALSE; break; case OP_ANYNL: case OP_VSPACE: SET_BIT(0x0A); SET_BIT(0x0B); SET_BIT(0x0C); SET_BIT(0x0D); #ifdef SUPPORT_UTF if (utf) { #ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ #endif #ifdef COMPILE_PCRE16 SET_BIT(0x85); SET_BIT(0xFF); /* For characters > 255 */ #endif } else #endif /* SUPPORT_UTF */ { SET_BIT(0x85); #ifdef COMPILE_PCRE16 SET_BIT(0xFF); /* For characters > 255 */ #endif } try_next = FALSE; break; /* Single character types set the bits and stop. Note that if PCRE_UCP is set, we do not see these op codes because \d etc are converted to properties. Therefore, these apply in the case when only characters less than 256 are recognized to match the types. */ case OP_NOT_DIGIT: set_nottype_bits(start_bits, cbit_digit, table_limit, cd); try_next = FALSE; break; case OP_DIGIT: set_type_bits(start_bits, cbit_digit, table_limit, cd); try_next = FALSE; break; /* The cbit_space table has vertical tab as whitespace; we have to ensure it is set as not whitespace. */ case OP_NOT_WHITESPACE: set_nottype_bits(start_bits, cbit_space, table_limit, cd); start_bits[1] |= 0x08; try_next = FALSE; break; /* The cbit_space table has vertical tab as whitespace; we have to not set it from the table. */ case OP_WHITESPACE: c = start_bits[1]; /* Save in case it was already set */ set_type_bits(start_bits, cbit_space, table_limit, cd); start_bits[1] = (start_bits[1] & ~0x08) | c; try_next = FALSE; break; case OP_NOT_WORDCHAR: set_nottype_bits(start_bits, cbit_word, table_limit, cd); try_next = FALSE; break; case OP_WORDCHAR: set_type_bits(start_bits, cbit_word, table_limit, cd); try_next = FALSE; break; /* One or more character type fudges the pointer and restarts, knowing it will hit a single character type and stop there. */ case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: tcode++; break; case OP_TYPEEXACT: tcode += 1 + IMM2_SIZE; break; /* Zero or more repeats of character types set the bits and then try again. */ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: tcode += IMM2_SIZE; /* Fall through */ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: switch(tcode[1]) { default: case OP_ANY: case OP_ALLANY: return SSB_FAIL; case OP_HSPACE: SET_BIT(0x09); SET_BIT(0x20); #ifdef SUPPORT_UTF if (utf) { #ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+00A0 */ SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ #endif #ifdef COMPILE_PCRE16 SET_BIT(0xA0); SET_BIT(0xFF); /* For characters > 255 */ #endif } else #endif /* SUPPORT_UTF */ SET_BIT(0xA0); break; case OP_ANYNL: case OP_VSPACE: SET_BIT(0x0A); SET_BIT(0x0B); SET_BIT(0x0C); SET_BIT(0x0D); #ifdef SUPPORT_UTF if (utf) { #ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ #endif #ifdef COMPILE_PCRE16 SET_BIT(0x85); SET_BIT(0xFF); /* For characters > 255 */ #endif } else #endif /* SUPPORT_UTF */ SET_BIT(0x85); break; case OP_NOT_DIGIT: set_nottype_bits(start_bits, cbit_digit, table_limit, cd); break; case OP_DIGIT: set_type_bits(start_bits, cbit_digit, table_limit, cd); break; /* The cbit_space table has vertical tab as whitespace; we have to ensure it gets set as not whitespace. */ case OP_NOT_WHITESPACE: set_nottype_bits(start_bits, cbit_space, table_limit, cd); start_bits[1] |= 0x08; break; /* The cbit_space table has vertical tab as whitespace; we have to avoid setting it. */ case OP_WHITESPACE: c = start_bits[1]; /* Save in case it was already set */ set_type_bits(start_bits, cbit_space, table_limit, cd); start_bits[1] = (start_bits[1] & ~0x08) | c; break; case OP_NOT_WORDCHAR: set_nottype_bits(start_bits, cbit_word, table_limit, cd); break; case OP_WORDCHAR: set_type_bits(start_bits, cbit_word, table_limit, cd); break; } tcode += 2; break; /* Character class where all the information is in a bit map: set the bits and either carry on or not, according to the repeat count. If it was a negative class, and we are operating with UTF-8 characters, any byte with a value >= 0xc4 is a potentially valid starter because it starts a character with a value > 255. */ case OP_NCLASS: #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (utf) { start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } #endif #ifdef COMPILE_PCRE16 SET_BIT(0xFF); /* For characters > 255 */ #endif /* Fall through */ case OP_CLASS: { pcre_uint8 *map; tcode++; map = (pcre_uint8 *)tcode; /* In UTF-8 mode, the bits in a bit map correspond to character values, not to byte values. However, the bit map we are constructing is for byte values. So we have to do a conversion for characters whose value is > 127. In fact, there are only two possible starting bytes for characters in the range 128 - 255. */ #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (utf) { for (c = 0; c < 16; c++) start_bits[c] |= map[c]; for (c = 128; c < 256; c++) { if ((map[c/8] && (1 << (c&7))) != 0) { int d = (c >> 6) | 0xc0; /* Set bit for this starter */ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ } } } else #endif { /* In non-UTF-8 mode, the two bit maps are completely compatible. */ for (c = 0; c < 32; c++) start_bits[c] |= map[c]; } /* Advance past the bit map, and act on what follows. For a zero minimum repeat, continue; otherwise stop processing. */ tcode += 32 / sizeof(pcre_uchar); switch (*tcode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: tcode++; break; case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE; else try_next = FALSE; break; default: try_next = FALSE; break; } } break; /* End of bitmap class handling */ } /* End of switch */ } /* End of try_next loop */ code += GET(code, 1); /* Advance to next branch */ } while (*code == OP_ALT); return yield; } /************************************************* * Study a compiled expression * *************************************************/ /* This function is handed a compiled expression that it must study to produce information that will speed up the matching. It returns a pcre[16]_extra block which then gets handed back to pcre_exec(). Arguments: re points to the compiled expression options contains option bits errorptr points to where to place error messages; set NULL unless error Returns: pointer to a pcre[16]_extra block, with study_data filled in and the appropriate flags set; NULL on error or if no optimization possible */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION pcre_study(const pcre *external_re, int options, const char **errorptr) #else PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION pcre16_study(const pcre16 *external_re, int options, const char **errorptr) #endif { int min; BOOL bits_set = FALSE; pcre_uint8 start_bits[32]; PUBL(extra) *extra = NULL; pcre_study_data *study; const pcre_uint8 *tables; pcre_uchar *code; compile_data compile_block; const REAL_PCRE *re = (const REAL_PCRE *)external_re; *errorptr = NULL; if (re == NULL || re->magic_number != MAGIC_NUMBER) { *errorptr = "argument is not a compiled regular expression"; return NULL; } if ((re->flags & PCRE_MODE) == 0) { #ifdef COMPILE_PCRE8 *errorptr = "argument is compiled in 16 bit mode"; #else *errorptr = "argument is compiled in 8 bit mode"; #endif return NULL; } if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) { *errorptr = "unknown or incorrect option bit(s) set"; return NULL; } code = (pcre_uchar *)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", there is no point in seeking a list of starting bytes. */ if ((re->options & PCRE_ANCHORED) == 0 && (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0) { int rc; /* Set the character tables in the block that is passed around */ tables = re->tables; #ifdef COMPILE_PCRE8 if (tables == NULL) (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void *)(&tables)); #else if (tables == NULL) (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void *)(&tables)); #endif compile_block.lcc = tables + lcc_offset; compile_block.fcc = tables + fcc_offset; compile_block.cbits = tables + cbits_offset; compile_block.ctypes = tables + ctypes_offset; /* See if we can find a fixed set of initial characters for the pattern. */ memset(start_bits, 0, 32 * sizeof(pcre_uint8)); rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0, &compile_block); bits_set = rc == SSB_DONE; if (rc == SSB_UNKNOWN) { *errorptr = "internal error: opcode not recognized"; return NULL; } } /* Find the minimum length of subject string. */ switch(min = find_minlength(code, code, re->options, 0)) { case -2: *errorptr = "internal error: missing capturing bracket"; return NULL; case -3: *errorptr = "internal error: opcode not recognized"; return NULL; default: break; } /* If a set of starting bytes has been identified, or if the minimum length is greater than zero, or if JIT optimization has been requested, get a pcre[16]_extra block and a pcre_study_data block. The study data is put in the latter, which is pointed to by the former, which may also get additional data set later by the calling program. At the moment, the size of pcre_study_data is fixed. We nevertheless save it in a field for returning via the pcre_fullinfo() function so that if it becomes variable in the future, we don't have to change that code. */ if (bits_set || min > 0 #ifdef SUPPORT_JIT || (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE | PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0 #endif ) { extra = (PUBL(extra) *)(PUBL(malloc)) (sizeof(PUBL(extra)) + sizeof(pcre_study_data)); if (extra == NULL) { *errorptr = "failed to get memory"; return NULL; } study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra))); extra->flags = PCRE_EXTRA_STUDY_DATA; extra->study_data = study; study->size = sizeof(pcre_study_data); study->flags = 0; /* Set the start bits always, to avoid unset memory errors if the study data is written to a file, but set the flag only if any of the bits are set, to save time looking when none are. */ if (bits_set) { study->flags |= PCRE_STUDY_MAPPED; memcpy(study->start_bits, start_bits, sizeof(start_bits)); } else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8)); #ifdef PCRE_DEBUG if (bits_set) { pcre_uint8 *ptr = start_bits; int i; printf("Start bits:\n"); for (i = 0; i < 32; i++) printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n"); } #endif /* Always set the minlength value in the block, because the JIT compiler makes use of it. However, don't set the bit unless the length is greater than zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time checking the zero case. */ if (min > 0) { study->flags |= PCRE_STUDY_MINLEN; study->minlength = min; } else study->minlength = 0; /* If JIT support was compiled and requested, attempt the JIT compilation. If no starting bytes were found, and the minimum length is zero, and JIT compilation fails, abandon the extra block and return NULL. */ #ifdef SUPPORT_JIT extra->executable_jit = NULL; if ((options & PCRE_STUDY_JIT_COMPILE) != 0) PRIV(jit_compile)(re, extra, JIT_COMPILE); if ((options & PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE) != 0) PRIV(jit_compile)(re, extra, JIT_PARTIAL_SOFT_COMPILE); if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0) PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE); if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0) { #ifdef COMPILE_PCRE8 pcre_free_study(extra); #endif #ifdef COMPILE_PCRE16 pcre16_free_study(extra); #endif extra = NULL; } #endif } return extra; } /************************************************* * Free the study data * *************************************************/ /* This function frees the memory that was obtained by pcre_study(). Argument: a pointer to the pcre[16]_extra block Returns: nothing */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void pcre_free_study(pcre_extra *extra) #else PCRE_EXP_DEFN void pcre16_free_study(pcre16_extra *extra) #endif { if (extra == NULL) return; #ifdef SUPPORT_JIT if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) PRIV(jit_free)(extra->executable_jit); #endif PUBL(free)(extra); } /* End of pcre_study.c */ pcre-8.31/pcre_internal.h0000644000222100022210000027176211767400230012320 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This header contains definitions that are shared between the different modules, but which are not relevant to the exported API. This includes some functions whose names all begin with "_pcre_" or "_pcre16_" depending on the PRIV macro. */ #ifndef PCRE_INTERNAL_H #define PCRE_INTERNAL_H /* Define PCRE_DEBUG to get debugging output on stdout. */ #if 0 #define PCRE_DEBUG #endif /* PCRE is compiled as an 8 bit library if it is not requested otherwise. */ #ifndef COMPILE_PCRE16 #define COMPILE_PCRE8 #endif /* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The "configure" script ensures this, but not everybody uses "configure". */ #if defined SUPPORT_UCP && !(defined SUPPORT_UTF) #define SUPPORT_UTF 1 #endif /* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility reasons with existing code. */ #if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF) #define SUPPORT_UTF 1 #endif /* Fixme: SUPPORT_UTF8 should be eventually disappear from the code. Until then we define it if SUPPORT_UTF is defined. */ #if defined SUPPORT_UTF && !(defined SUPPORT_UTF8) #define SUPPORT_UTF8 1 #endif /* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure" script prevents both being selected, but not everybody uses "configure". */ #if defined EBCDIC && defined SUPPORT_UTF #error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported. #endif /* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef inline, and there are *still* stupid compilers about that don't like indented pre-processor statements, or at least there were when I first wrote this. After all, it had only been about 10 years then... It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so be absolutely sure we get our version. */ #undef DPRINTF #ifdef PCRE_DEBUG #define DPRINTF(p) printf p #else #define DPRINTF(p) /* Nothing */ #endif /* Standard C headers plus the external interface definition. The only time setjmp and stdarg are used is when NO_RECURSE is set. */ #include #include #include #include #include #include /* When compiling a DLL for Windows, the exported symbols have to be declared using some MS magic. I found some useful information on this web page: http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the information there, using __declspec(dllexport) without "extern" we have a definition; with "extern" we have a declaration. The settings here override the setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL, which is all that is needed for applications (they just import the symbols). We use: PCRE_EXP_DECL for declarations PCRE_EXP_DEFN for definitions of exported functions PCRE_EXP_DATA_DEFN for definitions of exported variables The reason for the two DEFN macros is that in non-Windows environments, one does not want to have "extern" before variable definitions because it leads to compiler warnings. So we distinguish between functions and variables. In Windows, the two should always be the same. The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest, which is an application, but needs to import this file in order to "peek" at internals, can #include pcre.h first to get an application's-eye view. In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon, special-purpose environments) might want to stick other stuff in front of exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and PCRE_EXP_DATA_DEFN only if they are not already set. */ #ifndef PCRE_EXP_DECL # ifdef _WIN32 # ifndef PCRE_STATIC # define PCRE_EXP_DECL extern __declspec(dllexport) # define PCRE_EXP_DEFN __declspec(dllexport) # define PCRE_EXP_DATA_DEFN __declspec(dllexport) # else # define PCRE_EXP_DECL extern # define PCRE_EXP_DEFN # define PCRE_EXP_DATA_DEFN # endif # else # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif # ifndef PCRE_EXP_DEFN # define PCRE_EXP_DEFN PCRE_EXP_DECL # endif # ifndef PCRE_EXP_DATA_DEFN # define PCRE_EXP_DATA_DEFN # endif # endif #endif /* When compiling with the MSVC compiler, it is sometimes necessary to include a "calling convention" before exported function names. (This is secondhand information; I know nothing about MSVC myself). For example, something like void __cdecl function(....) might be needed. In order so make this easy, all the exported functions have PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not set, we ensure here that it has no effect. */ #ifndef PCRE_CALL_CONVENTION #define PCRE_CALL_CONVENTION #endif /* We need to have types that specify unsigned 8, 16 and 32-bit integers. We cannot determine these outside the compilation (e.g. by running a program as part of "configure") because PCRE is often cross-compiled for use on other systems. Instead we make use of the maximum sizes that are available at preprocessor time in standard C environments. */ typedef unsigned char pcre_uint8; #if USHRT_MAX == 65535 typedef unsigned short pcre_uint16; typedef short pcre_int16; #elif UINT_MAX == 65535 typedef unsigned int pcre_uint16; typedef int pcre_int16; #else #error Cannot determine a type for 16-bit unsigned integers #endif #if UINT_MAX == 4294967295 typedef unsigned int pcre_uint32; typedef int pcre_int32; #elif ULONG_MAX == 4294967295 typedef unsigned long int pcre_uint32; typedef long int pcre_int32; #else #error Cannot determine a type for 32-bit unsigned integers #endif /* When checking for integer overflow in pcre_compile(), we need to handle large integers. If a 64-bit integer type is available, we can use that. Otherwise we have to cast to double, which of course requires floating point arithmetic. Handle this by defining a macro for the appropriate type. If stdint.h is available, include it; it may define INT64_MAX. Systems that do not have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set by "configure". */ #if HAVE_STDINT_H #include #elif HAVE_INTTYPES_H #include #endif #if defined INT64_MAX || defined int64_t #define INT64_OR_DOUBLE int64_t #else #define INT64_OR_DOUBLE double #endif /* All character handling must be done as unsigned characters. Otherwise there are problems with top-bit-set characters and functions such as isspace(). However, we leave the interface to the outside world as char * or short *, because that should make things easier for callers. This character type is called pcre_uchar. The IN_UCHARS macro multiply its argument with the byte size of the current pcre_uchar type. Useful for memcpy and such operations, whose require the byte size of their input/output buffers. The MAX_255 macro checks whether its pcre_uchar input is less than 256. The TABLE_GET macro is designed for accessing elements of tables whose contain exactly 256 items. When the character is able to contain more than 256 items, some check is needed before accessing these tables. */ #ifdef COMPILE_PCRE8 typedef unsigned char pcre_uchar; #define IN_UCHARS(x) (x) #define MAX_255(c) 1 #define TABLE_GET(c, table, default) ((table)[c]) #else #ifdef COMPILE_PCRE16 #if USHRT_MAX != 65535 /* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in pcre.h(.in) and disable (comment out) this message. */ #error Warning: PCRE_UCHAR16 is not a 16 bit data type. #endif typedef pcre_uint16 pcre_uchar; #define IN_UCHARS(x) ((x) << 1) #define MAX_255(c) ((c) <= 255u) #define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) #else #error Unsupported compiling mode #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ /* This is an unsigned int value that no character can ever have. UTF-8 characters only go up to 0x7fffffff (though Unicode doesn't go beyond 0x0010ffff). */ #define NOTACHAR 0xffffffff /* PCRE is able to support several different kinds of newline (CR, LF, CRLF, "any" and "anycrlf" at present). The following macros are used to package up testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various modules to indicate in which datablock the parameters exist, and what the start/end of string field names are. */ #define NLTYPE_FIXED 0 /* Newline is a fixed length string */ #define NLTYPE_ANY 1 /* Newline is any Unicode line ending */ #define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */ /* This macro checks for a newline at the given position */ #define IS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) < NLBLOCK->PSEND && \ PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \ &(NLBLOCK->nllen), utf)) \ : \ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ (p)[0] == NLBLOCK->nl[0] && \ (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \ ) \ ) /* This macro checks for a newline immediately preceding the given position */ #define WAS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) > NLBLOCK->PSSTART && \ PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ &(NLBLOCK->nllen), utf)) \ : \ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \ (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+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 class. It must always be possible to inspect all of the subject string in pcre_exec() because of the way it backtracks. Two macros are required in the normal case, for sign-unspecified and unsigned char pointers. The former is used for the external interface and appears in pcre.h, which is why its name must begin with PCRE_. */ #ifdef CUSTOM_SUBJECT_PTR #define PCRE_PUCHAR CUSTOM_SUBJECT_PTR #else #define PCRE_PUCHAR const pcre_uchar * #endif /* Include the public PCRE header and the definitions of UCP character property values. */ #include "pcre.h" #include "ucp.h" /* When compiling for use with the Virtual Pascal compiler, these functions need to have their names changed. PCRE must be compiled with the -DVPCOMPAT option on the command line. */ #ifdef VPCOMPAT #define strlen(s) _strlen(s) #define strncmp(s1,s2,m) _strncmp(s1,s2,m) #define memcmp(s,c,n) _memcmp(s,c,n) #define memcpy(d,s,n) _memcpy(d,s,n) #define memmove(d,s,n) _memmove(d,s,n) #define memset(s,c,n) _memset(s,c,n) #else /* VPCOMPAT */ /* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), 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). */ #ifndef HAVE_MEMMOVE #undef memmove /* some systems may have a macro */ #ifdef HAVE_BCOPY #define memmove(a, b, c) bcopy(b, a, c) #else /* HAVE_BCOPY */ static void * pcre_memmove(void *d, const void *s, size_t n) { size_t i; unsigned char *dest = (unsigned char *)d; const unsigned char *src = (const unsigned char *)s; if (dest > src) { dest += n; src += n; for (i = 0; i < n; ++i) *(--dest) = *(--src); return (void *)dest; } else { for (i = 0; i < n; ++i) *dest++ = *src++; return (void *)(dest - n); } } #define memmove(a, b, c) pcre_memmove(a, b, c) #endif /* not HAVE_BCOPY */ #endif /* not HAVE_MEMMOVE */ #endif /* not VPCOMPAT */ /* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored in big-endian order) by default. These are used, for example, to link from the start of a subpattern to its alternatives and its end. The use of 2 bytes per offset limits the size of the compiled regex to around 64K, which is big enough for almost everybody. However, I received a request for an even bigger limit. For this reason, and also to make the code easier to maintain, the storing and loading of offsets from the byte string is now handled by the macros that are defined here. The macros are controlled by the value of LINK_SIZE. This defaults to 2 in the config.h file, but can be overridden by using -D on the command line. This is automated on Unix systems via the "configure" command. */ #ifdef COMPILE_PCRE8 #if LINK_SIZE == 2 #define PUT(a,n,d) \ (a[n] = (d) >> 8), \ (a[(n)+1] = (d) & 255) #define GET(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) #define MAX_PATTERN_SIZE (1 << 16) #elif LINK_SIZE == 3 #define PUT(a,n,d) \ (a[n] = (d) >> 16), \ (a[(n)+1] = (d) >> 8), \ (a[(n)+2] = (d) & 255) #define GET(a,n) \ (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) #define MAX_PATTERN_SIZE (1 << 24) #elif LINK_SIZE == 4 #define PUT(a,n,d) \ (a[n] = (d) >> 24), \ (a[(n)+1] = (d) >> 16), \ (a[(n)+2] = (d) >> 8), \ (a[(n)+3] = (d) & 255) #define GET(a,n) \ (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) /* Keep it positive */ #define MAX_PATTERN_SIZE (1 << 30) #else #error LINK_SIZE must be either 2, 3, or 4 #endif #else /* COMPILE_PCRE8 */ #ifdef COMPILE_PCRE16 #if LINK_SIZE == 2 #undef LINK_SIZE #define LINK_SIZE 1 #define PUT(a,n,d) \ (a[n] = (d)) #define GET(a,n) \ (a[n]) #define MAX_PATTERN_SIZE (1 << 16) #elif LINK_SIZE == 3 || LINK_SIZE == 4 #undef LINK_SIZE #define LINK_SIZE 2 #define PUT(a,n,d) \ (a[n] = (d) >> 16), \ (a[(n)+1] = (d) & 65535) #define GET(a,n) \ (((a)[n] << 16) | (a)[(n)+1]) /* Keep it positive */ #define MAX_PATTERN_SIZE (1 << 30) #else #error LINK_SIZE must be either 2, 3, or 4 #endif #else #error Unsupported compiling mode #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ /* Convenience macro defined in terms of the others */ #define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE /* PCRE uses some other 2-byte quantities that do not change when the size of offsets changes. There are used for repeat counts and for other things such as capturing parenthesis numbers in back references. */ #ifdef COMPILE_PCRE8 #define IMM2_SIZE 2 #define PUT2(a,n,d) \ a[n] = (d) >> 8; \ a[(n)+1] = (d) & 255 #define GET2(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) #else /* COMPILE_PCRE8 */ #ifdef COMPILE_PCRE16 #define IMM2_SIZE 1 #define PUT2(a,n,d) \ a[n] = d #define GET2(a,n) \ a[n] #else #error Unsupported compiling mode #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ #define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE /* The maximum length of a MARK name is currently one data unit; it may be changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */ #define MAX_MARK ((1 << (sizeof(pcre_uchar)*8)) - 1) /* When UTF encoding is being used, a character is no longer just a single character. The macros for character handling generate simple sequences when used in character-mode, and more complicated ones for UTF characters. GETCHARLENTEST and other macros are not used when UTF is not supported, so they are not defined. To make sure they can never even appear when UTF support is omitted, we don't even define them. */ #ifndef SUPPORT_UTF /* #define MAX_VALUE_FOR_SINGLE_CHAR */ /* #define HAS_EXTRALEN(c) */ /* #define GET_EXTRALEN(c) */ /* #define NOT_FIRSTCHAR(c) */ #define GETCHAR(c, eptr) c = *eptr; #define GETCHARTEST(c, eptr) c = *eptr; #define GETCHARINC(c, eptr) c = *eptr++; #define GETCHARINCTEST(c, eptr) c = *eptr++; #define GETCHARLEN(c, eptr, len) c = *eptr; /* #define GETCHARLENTEST(c, eptr, len) */ /* #define BACKCHAR(eptr) */ /* #define FORWARDCHAR(eptr) */ /* #define ACROSSCHAR(condition, eptr, action) */ #else /* SUPPORT_UTF */ #ifdef COMPILE_PCRE8 /* These macros were originally written in the form of loops that used data from the tables whose names start with PRIV(utf8_table). They were rewritten by a user so as not to use loops, because in some environments this gives a significant performance advantage, and it seems never to do any harm. */ /* Tells the biggest code point which can be encoded as a single character. */ #define MAX_VALUE_FOR_SINGLE_CHAR 127 /* Tests whether the code point needs extra characters to decode. */ #define HAS_EXTRALEN(c) ((c) >= 0xc0) /* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. Otherwise it has an undefined behaviour. */ #define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) /* Returns TRUE, if the given character is not the first character of a UTF sequence. */ #define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80) /* Base macro to pick up the remaining bytes of a UTF-8 character, not advancing the pointer. */ #define GETUTF8(c, eptr) \ { \ if ((c & 0x20) == 0) \ c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ else if ((c & 0x10) == 0) \ c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ else if ((c & 0x08) == 0) \ c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ else if ((c & 0x04) == 0) \ c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ (eptr[4] & 0x3f); \ else \ c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ } /* Get the next UTF-8 character, not advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHAR(c, eptr) \ c = *eptr; \ if (c >= 0xc0) GETUTF8(c, eptr); /* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the pointer. */ #define GETCHARTEST(c, eptr) \ c = *eptr; \ if (utf && c >= 0xc0) GETUTF8(c, eptr); /* Base macro to pick up the remaining bytes of a UTF-8 character, advancing the pointer. */ #define GETUTF8INC(c, eptr) \ { \ if ((c & 0x20) == 0) \ c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \ else if ((c & 0x10) == 0) \ { \ c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \ eptr += 2; \ } \ else if ((c & 0x08) == 0) \ { \ c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \ ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ eptr += 3; \ } \ else if ((c & 0x04) == 0) \ { \ c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \ ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \ (eptr[3] & 0x3f); \ eptr += 4; \ } \ else \ { \ c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \ ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \ ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \ eptr += 5; \ } \ } /* Get the next UTF-8 character, advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHARINC(c, eptr) \ c = *eptr++; \ if (c >= 0xc0) GETUTF8INC(c, eptr); /* Get the next character, testing for UTF-8 mode, and advancing the pointer. This is called when we don't know if we are in UTF-8 mode. */ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ if (utf && c >= 0xc0) GETUTF8INC(c, eptr); /* Base macro to pick up the remaining bytes of a UTF-8 character, not advancing the pointer, incrementing the length. */ #define GETUTF8LEN(c, eptr, len) \ { \ if ((c & 0x20) == 0) \ { \ c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ len++; \ } \ else if ((c & 0x10) == 0) \ { \ c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ len += 2; \ } \ else if ((c & 0x08) == 0) \ {\ c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ len += 3; \ } \ else if ((c & 0x04) == 0) \ { \ c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ (eptr[4] & 0x3f); \ len += 4; \ } \ else \ {\ c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ len += 5; \ } \ } /* Get the next UTF-8 character, not advancing the pointer, incrementing length if there are extra bytes. This is called when we know we are in UTF-8 mode. */ #define GETCHARLEN(c, eptr, len) \ c = *eptr; \ if (c >= 0xc0) GETUTF8LEN(c, eptr, len); /* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the pointer, incrementing length if there are extra bytes. This is called when we do not know if we are in UTF-8 mode. */ #define GETCHARLENTEST(c, eptr, len) \ c = *eptr; \ if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-8 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-8 only code. */ #define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- /* Same as above, just in the other direction. */ #define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++ /* Same as above, but it allows a fully customizable form. */ #define ACROSSCHAR(condition, eptr, action) \ while((condition) && ((eptr) & 0xc0) == 0x80) action #else /* COMPILE_PCRE8 */ #ifdef COMPILE_PCRE16 /* Tells the biggest code point which can be encoded as a single character. */ #define MAX_VALUE_FOR_SINGLE_CHAR 65535 /* Tests whether the code point needs extra characters to decode. */ #define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800) /* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. Otherwise it has an undefined behaviour. */ #define GET_EXTRALEN(c) 1 /* Returns TRUE, if the given character is not the first character of a UTF sequence. */ #define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00) /* Base macro to pick up the low surrogate of a UTF-16 character, not advancing the pointer. */ #define GETUTF16(c, eptr) \ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; } /* Get the next UTF-16 character, not advancing the pointer. This is called when we know we are in UTF-16 mode. */ #define GETCHAR(c, eptr) \ c = *eptr; \ if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr); /* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the pointer. */ #define GETCHARTEST(c, eptr) \ c = *eptr; \ if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr); /* Base macro to pick up the low surrogate of a UTF-16 character, advancing the pointer. */ #define GETUTF16INC(c, eptr) \ { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; } /* Get the next UTF-16 character, advancing the pointer. This is called when we know we are in UTF-16 mode. */ #define GETCHARINC(c, eptr) \ c = *eptr++; \ if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); /* Get the next character, testing for UTF-16 mode, and advancing the pointer. This is called when we don't know if we are in UTF-16 mode. */ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); /* Base macro to pick up the low surrogate of a UTF-16 character, not advancing the pointer, incrementing the length. */ #define GETUTF16LEN(c, eptr, len) \ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; } /* Get the next UTF-16 character, not advancing the pointer, incrementing length if there is a low surrogate. This is called when we know we are in UTF-16 mode. */ #define GETCHARLEN(c, eptr, len) \ c = *eptr; \ if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); /* Get the next UTF-816character, testing for UTF-16 mode, not advancing the pointer, incrementing length if there is a low surrogate. This is called when we do not know if we are in UTF-16 mode. */ #define GETCHARLENTEST(c, eptr, len) \ c = *eptr; \ if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-16 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-16 only code. */ #define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr-- /* Same as above, just in the other direction. */ #define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++ /* Same as above, but it allows a fully customizable form. */ #define ACROSSCHAR(condition, eptr, action) \ if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action #endif #endif /* COMPILE_PCRE8 */ #endif /* SUPPORT_UTF */ /* In case there is no definition of offsetof() provided - though any proper Standard C system should have one. */ #ifndef offsetof #define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field)) #endif /* Private flags containing information about the compiled regex. They used to live at the top end of the options word, but that got almost full, so now they are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as the restrictions on partial matching have been lifted. It remains for backwards compatibility. */ #ifdef COMPILE_PCRE8 #define PCRE_MODE 0x0001 /* compiled in 8 bit mode */ #endif #ifdef COMPILE_PCRE16 #define PCRE_MODE 0x0002 /* compiled in 16 bit mode */ #endif #define PCRE_FIRSTSET 0x0010 /* first_char is set */ #define PCRE_FCH_CASELESS 0x0020 /* caseless first char */ #define PCRE_REQCHSET 0x0040 /* req_byte is set */ #define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */ #define PCRE_STARTLINE 0x0100 /* start after \n for multiline */ #define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */ #define PCRE_JCHANGED 0x0400 /* j option used in regex */ #define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */ #define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */ /* Flags for the "extra" block produced by pcre_study(). */ #define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */ #define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */ /* Masks for identifying the public options that are permitted at compile time, run time, or study time, respectively. */ #define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \ PCRE_NEWLINE_ANYCRLF) #define PUBLIC_COMPILE_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_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \ PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE) #define PUBLIC_EXEC_OPTIONS \ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \ PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \ PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE) #define PUBLIC_DFA_EXEC_OPTIONS \ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \ PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \ PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \ PCRE_NO_START_OPTIMIZE) #define PUBLIC_STUDY_OPTIONS \ (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) /* Magic number to provide a small check against being handed junk. */ #define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ /* This variable is used to detect a loaded regular expression in different endianness. */ #define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */ /* Negative values for the firstchar and reqchar variables */ #define REQ_UNSET (-2) #define REQ_NONE (-1) /* The maximum remaining length of subject we are prepared to search for a req_byte match. */ #define REQ_BYTE_MAX 1000 /* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in environments where these macros are defined elsewhere. Unfortunately, there is no way to do the same for the typedef. */ typedef int BOOL; #ifndef FALSE #define FALSE 0 #define TRUE 1 #endif /* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal character constants like '*' because the compiler would emit their EBCDIC code, which is different from their ASCII/UTF-8 code. Instead we define macros for the characters so that they always use the ASCII/UTF-8 code when UTF-8 support is enabled. When UTF-8 support is not enabled, the definitions use character literals. Both character and string versions of each character are needed, and there are some longer strings as well. This means that, on EBCDIC platforms, the PCRE library can handle either EBCDIC, or UTF-8, but not both. To support both in the same compiled library would need different lookups depending on whether PCRE_UTF8 was set or not. This would make it impossible to use characters in switch/case statements, which would reduce performance. For a theoretical use (which nobody has asked for) in a minority area (EBCDIC platforms), this is not sensible. Any application that did need both could compile two versions of the library, using macros to give the functions distinct names. */ #ifndef SUPPORT_UTF /* UTF-8 support is not enabled; use the platform-dependent character literals so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */ #define CHAR_HT '\t' #define CHAR_VT '\v' #define CHAR_FF '\f' #define CHAR_CR '\r' #define CHAR_NL '\n' #define CHAR_BS '\b' #define CHAR_BEL '\a' #ifdef EBCDIC #define CHAR_ESC '\047' #define CHAR_DEL '\007' #else #define CHAR_ESC '\033' #define CHAR_DEL '\177' #endif #define CHAR_SPACE ' ' #define CHAR_EXCLAMATION_MARK '!' #define CHAR_QUOTATION_MARK '"' #define CHAR_NUMBER_SIGN '#' #define CHAR_DOLLAR_SIGN '$' #define CHAR_PERCENT_SIGN '%' #define CHAR_AMPERSAND '&' #define CHAR_APOSTROPHE '\'' #define CHAR_LEFT_PARENTHESIS '(' #define CHAR_RIGHT_PARENTHESIS ')' #define CHAR_ASTERISK '*' #define CHAR_PLUS '+' #define CHAR_COMMA ',' #define CHAR_MINUS '-' #define CHAR_DOT '.' #define CHAR_SLASH '/' #define CHAR_0 '0' #define CHAR_1 '1' #define CHAR_2 '2' #define CHAR_3 '3' #define CHAR_4 '4' #define CHAR_5 '5' #define CHAR_6 '6' #define CHAR_7 '7' #define CHAR_8 '8' #define CHAR_9 '9' #define CHAR_COLON ':' #define CHAR_SEMICOLON ';' #define CHAR_LESS_THAN_SIGN '<' #define CHAR_EQUALS_SIGN '=' #define CHAR_GREATER_THAN_SIGN '>' #define CHAR_QUESTION_MARK '?' #define CHAR_COMMERCIAL_AT '@' #define CHAR_A 'A' #define CHAR_B 'B' #define CHAR_C 'C' #define CHAR_D 'D' #define CHAR_E 'E' #define CHAR_F 'F' #define CHAR_G 'G' #define CHAR_H 'H' #define CHAR_I 'I' #define CHAR_J 'J' #define CHAR_K 'K' #define CHAR_L 'L' #define CHAR_M 'M' #define CHAR_N 'N' #define CHAR_O 'O' #define CHAR_P 'P' #define CHAR_Q 'Q' #define CHAR_R 'R' #define CHAR_S 'S' #define CHAR_T 'T' #define CHAR_U 'U' #define CHAR_V 'V' #define CHAR_W 'W' #define CHAR_X 'X' #define CHAR_Y 'Y' #define CHAR_Z 'Z' #define CHAR_LEFT_SQUARE_BRACKET '[' #define CHAR_BACKSLASH '\\' #define CHAR_RIGHT_SQUARE_BRACKET ']' #define CHAR_CIRCUMFLEX_ACCENT '^' #define CHAR_UNDERSCORE '_' #define CHAR_GRAVE_ACCENT '`' #define CHAR_a 'a' #define CHAR_b 'b' #define CHAR_c 'c' #define CHAR_d 'd' #define CHAR_e 'e' #define CHAR_f 'f' #define CHAR_g 'g' #define CHAR_h 'h' #define CHAR_i 'i' #define CHAR_j 'j' #define CHAR_k 'k' #define CHAR_l 'l' #define CHAR_m 'm' #define CHAR_n 'n' #define CHAR_o 'o' #define CHAR_p 'p' #define CHAR_q 'q' #define CHAR_r 'r' #define CHAR_s 's' #define CHAR_t 't' #define CHAR_u 'u' #define CHAR_v 'v' #define CHAR_w 'w' #define CHAR_x 'x' #define CHAR_y 'y' #define CHAR_z 'z' #define CHAR_LEFT_CURLY_BRACKET '{' #define CHAR_VERTICAL_LINE '|' #define CHAR_RIGHT_CURLY_BRACKET '}' #define CHAR_TILDE '~' #define STR_HT "\t" #define STR_VT "\v" #define STR_FF "\f" #define STR_CR "\r" #define STR_NL "\n" #define STR_BS "\b" #define STR_BEL "\a" #ifdef EBCDIC #define STR_ESC "\047" #define STR_DEL "\007" #else #define STR_ESC "\033" #define STR_DEL "\177" #endif #define STR_SPACE " " #define STR_EXCLAMATION_MARK "!" #define STR_QUOTATION_MARK "\"" #define STR_NUMBER_SIGN "#" #define STR_DOLLAR_SIGN "$" #define STR_PERCENT_SIGN "%" #define STR_AMPERSAND "&" #define STR_APOSTROPHE "'" #define STR_LEFT_PARENTHESIS "(" #define STR_RIGHT_PARENTHESIS ")" #define STR_ASTERISK "*" #define STR_PLUS "+" #define STR_COMMA "," #define STR_MINUS "-" #define STR_DOT "." #define STR_SLASH "/" #define STR_0 "0" #define STR_1 "1" #define STR_2 "2" #define STR_3 "3" #define STR_4 "4" #define STR_5 "5" #define STR_6 "6" #define STR_7 "7" #define STR_8 "8" #define STR_9 "9" #define STR_COLON ":" #define STR_SEMICOLON ";" #define STR_LESS_THAN_SIGN "<" #define STR_EQUALS_SIGN "=" #define STR_GREATER_THAN_SIGN ">" #define STR_QUESTION_MARK "?" #define STR_COMMERCIAL_AT "@" #define STR_A "A" #define STR_B "B" #define STR_C "C" #define STR_D "D" #define STR_E "E" #define STR_F "F" #define STR_G "G" #define STR_H "H" #define STR_I "I" #define STR_J "J" #define STR_K "K" #define STR_L "L" #define STR_M "M" #define STR_N "N" #define STR_O "O" #define STR_P "P" #define STR_Q "Q" #define STR_R "R" #define STR_S "S" #define STR_T "T" #define STR_U "U" #define STR_V "V" #define STR_W "W" #define STR_X "X" #define STR_Y "Y" #define STR_Z "Z" #define STR_LEFT_SQUARE_BRACKET "[" #define STR_BACKSLASH "\\" #define STR_RIGHT_SQUARE_BRACKET "]" #define STR_CIRCUMFLEX_ACCENT "^" #define STR_UNDERSCORE "_" #define STR_GRAVE_ACCENT "`" #define STR_a "a" #define STR_b "b" #define STR_c "c" #define STR_d "d" #define STR_e "e" #define STR_f "f" #define STR_g "g" #define STR_h "h" #define STR_i "i" #define STR_j "j" #define STR_k "k" #define STR_l "l" #define STR_m "m" #define STR_n "n" #define STR_o "o" #define STR_p "p" #define STR_q "q" #define STR_r "r" #define STR_s "s" #define STR_t "t" #define STR_u "u" #define STR_v "v" #define STR_w "w" #define STR_x "x" #define STR_y "y" #define STR_z "z" #define STR_LEFT_CURLY_BRACKET "{" #define STR_VERTICAL_LINE "|" #define STR_RIGHT_CURLY_BRACKET "}" #define STR_TILDE "~" #define STRING_ACCEPT0 "ACCEPT\0" #define STRING_COMMIT0 "COMMIT\0" #define STRING_F0 "F\0" #define STRING_FAIL0 "FAIL\0" #define STRING_MARK0 "MARK\0" #define STRING_PRUNE0 "PRUNE\0" #define STRING_SKIP0 "SKIP\0" #define STRING_THEN "THEN" #define STRING_alpha0 "alpha\0" #define STRING_lower0 "lower\0" #define STRING_upper0 "upper\0" #define STRING_alnum0 "alnum\0" #define STRING_ascii0 "ascii\0" #define STRING_blank0 "blank\0" #define STRING_cntrl0 "cntrl\0" #define STRING_digit0 "digit\0" #define STRING_graph0 "graph\0" #define STRING_print0 "print\0" #define STRING_punct0 "punct\0" #define STRING_space0 "space\0" #define STRING_word0 "word\0" #define STRING_xdigit "xdigit" #define STRING_DEFINE "DEFINE" #define STRING_CR_RIGHTPAR "CR)" #define STRING_LF_RIGHTPAR "LF)" #define STRING_CRLF_RIGHTPAR "CRLF)" #define STRING_ANY_RIGHTPAR "ANY)" #define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" #define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" #define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" #ifdef COMPILE_PCRE8 #define STRING_UTF_RIGHTPAR "UTF8)" #endif #ifdef COMPILE_PCRE16 #define STRING_UTF_RIGHTPAR "UTF16)" #endif #define STRING_UCP_RIGHTPAR "UCP)" #define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" #else /* SUPPORT_UTF */ /* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode only. */ #define CHAR_HT '\011' #define CHAR_VT '\013' #define CHAR_FF '\014' #define CHAR_CR '\015' #define CHAR_NL '\012' #define CHAR_BS '\010' #define CHAR_BEL '\007' #define CHAR_ESC '\033' #define CHAR_DEL '\177' #define CHAR_SPACE '\040' #define CHAR_EXCLAMATION_MARK '\041' #define CHAR_QUOTATION_MARK '\042' #define CHAR_NUMBER_SIGN '\043' #define CHAR_DOLLAR_SIGN '\044' #define CHAR_PERCENT_SIGN '\045' #define CHAR_AMPERSAND '\046' #define CHAR_APOSTROPHE '\047' #define CHAR_LEFT_PARENTHESIS '\050' #define CHAR_RIGHT_PARENTHESIS '\051' #define CHAR_ASTERISK '\052' #define CHAR_PLUS '\053' #define CHAR_COMMA '\054' #define CHAR_MINUS '\055' #define CHAR_DOT '\056' #define CHAR_SLASH '\057' #define CHAR_0 '\060' #define CHAR_1 '\061' #define CHAR_2 '\062' #define CHAR_3 '\063' #define CHAR_4 '\064' #define CHAR_5 '\065' #define CHAR_6 '\066' #define CHAR_7 '\067' #define CHAR_8 '\070' #define CHAR_9 '\071' #define CHAR_COLON '\072' #define CHAR_SEMICOLON '\073' #define CHAR_LESS_THAN_SIGN '\074' #define CHAR_EQUALS_SIGN '\075' #define CHAR_GREATER_THAN_SIGN '\076' #define CHAR_QUESTION_MARK '\077' #define CHAR_COMMERCIAL_AT '\100' #define CHAR_A '\101' #define CHAR_B '\102' #define CHAR_C '\103' #define CHAR_D '\104' #define CHAR_E '\105' #define CHAR_F '\106' #define CHAR_G '\107' #define CHAR_H '\110' #define CHAR_I '\111' #define CHAR_J '\112' #define CHAR_K '\113' #define CHAR_L '\114' #define CHAR_M '\115' #define CHAR_N '\116' #define CHAR_O '\117' #define CHAR_P '\120' #define CHAR_Q '\121' #define CHAR_R '\122' #define CHAR_S '\123' #define CHAR_T '\124' #define CHAR_U '\125' #define CHAR_V '\126' #define CHAR_W '\127' #define CHAR_X '\130' #define CHAR_Y '\131' #define CHAR_Z '\132' #define CHAR_LEFT_SQUARE_BRACKET '\133' #define CHAR_BACKSLASH '\134' #define CHAR_RIGHT_SQUARE_BRACKET '\135' #define CHAR_CIRCUMFLEX_ACCENT '\136' #define CHAR_UNDERSCORE '\137' #define CHAR_GRAVE_ACCENT '\140' #define CHAR_a '\141' #define CHAR_b '\142' #define CHAR_c '\143' #define CHAR_d '\144' #define CHAR_e '\145' #define CHAR_f '\146' #define CHAR_g '\147' #define CHAR_h '\150' #define CHAR_i '\151' #define CHAR_j '\152' #define CHAR_k '\153' #define CHAR_l '\154' #define CHAR_m '\155' #define CHAR_n '\156' #define CHAR_o '\157' #define CHAR_p '\160' #define CHAR_q '\161' #define CHAR_r '\162' #define CHAR_s '\163' #define CHAR_t '\164' #define CHAR_u '\165' #define CHAR_v '\166' #define CHAR_w '\167' #define CHAR_x '\170' #define CHAR_y '\171' #define CHAR_z '\172' #define CHAR_LEFT_CURLY_BRACKET '\173' #define CHAR_VERTICAL_LINE '\174' #define CHAR_RIGHT_CURLY_BRACKET '\175' #define CHAR_TILDE '\176' #define STR_HT "\011" #define STR_VT "\013" #define STR_FF "\014" #define STR_CR "\015" #define STR_NL "\012" #define STR_BS "\010" #define STR_BEL "\007" #define STR_ESC "\033" #define STR_DEL "\177" #define STR_SPACE "\040" #define STR_EXCLAMATION_MARK "\041" #define STR_QUOTATION_MARK "\042" #define STR_NUMBER_SIGN "\043" #define STR_DOLLAR_SIGN "\044" #define STR_PERCENT_SIGN "\045" #define STR_AMPERSAND "\046" #define STR_APOSTROPHE "\047" #define STR_LEFT_PARENTHESIS "\050" #define STR_RIGHT_PARENTHESIS "\051" #define STR_ASTERISK "\052" #define STR_PLUS "\053" #define STR_COMMA "\054" #define STR_MINUS "\055" #define STR_DOT "\056" #define STR_SLASH "\057" #define STR_0 "\060" #define STR_1 "\061" #define STR_2 "\062" #define STR_3 "\063" #define STR_4 "\064" #define STR_5 "\065" #define STR_6 "\066" #define STR_7 "\067" #define STR_8 "\070" #define STR_9 "\071" #define STR_COLON "\072" #define STR_SEMICOLON "\073" #define STR_LESS_THAN_SIGN "\074" #define STR_EQUALS_SIGN "\075" #define STR_GREATER_THAN_SIGN "\076" #define STR_QUESTION_MARK "\077" #define STR_COMMERCIAL_AT "\100" #define STR_A "\101" #define STR_B "\102" #define STR_C "\103" #define STR_D "\104" #define STR_E "\105" #define STR_F "\106" #define STR_G "\107" #define STR_H "\110" #define STR_I "\111" #define STR_J "\112" #define STR_K "\113" #define STR_L "\114" #define STR_M "\115" #define STR_N "\116" #define STR_O "\117" #define STR_P "\120" #define STR_Q "\121" #define STR_R "\122" #define STR_S "\123" #define STR_T "\124" #define STR_U "\125" #define STR_V "\126" #define STR_W "\127" #define STR_X "\130" #define STR_Y "\131" #define STR_Z "\132" #define STR_LEFT_SQUARE_BRACKET "\133" #define STR_BACKSLASH "\134" #define STR_RIGHT_SQUARE_BRACKET "\135" #define STR_CIRCUMFLEX_ACCENT "\136" #define STR_UNDERSCORE "\137" #define STR_GRAVE_ACCENT "\140" #define STR_a "\141" #define STR_b "\142" #define STR_c "\143" #define STR_d "\144" #define STR_e "\145" #define STR_f "\146" #define STR_g "\147" #define STR_h "\150" #define STR_i "\151" #define STR_j "\152" #define STR_k "\153" #define STR_l "\154" #define STR_m "\155" #define STR_n "\156" #define STR_o "\157" #define STR_p "\160" #define STR_q "\161" #define STR_r "\162" #define STR_s "\163" #define STR_t "\164" #define STR_u "\165" #define STR_v "\166" #define STR_w "\167" #define STR_x "\170" #define STR_y "\171" #define STR_z "\172" #define STR_LEFT_CURLY_BRACKET "\173" #define STR_VERTICAL_LINE "\174" #define STR_RIGHT_CURLY_BRACKET "\175" #define STR_TILDE "\176" #define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0" #define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0" #define STRING_F0 STR_F "\0" #define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0" #define STRING_MARK0 STR_M STR_A STR_R STR_K "\0" #define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0" #define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0" #define STRING_THEN STR_T STR_H STR_E STR_N #define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" #define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" #define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0" #define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0" #define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0" #define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0" #define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0" #define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0" #define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0" #define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0" #define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0" #define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0" #define STRING_word0 STR_w STR_o STR_r STR_d "\0" #define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t #define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E #define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS #define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS #define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS #ifdef COMPILE_PCRE8 #define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS #endif #ifdef COMPILE_PCRE16 #define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS #endif #define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS #define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS #endif /* SUPPORT_UTF */ /* Escape items that are just an encoding of a particular data value. */ #ifndef ESC_e #define ESC_e CHAR_ESC #endif #ifndef ESC_f #define ESC_f CHAR_FF #endif #ifndef ESC_n #define ESC_n CHAR_NL #endif #ifndef ESC_r #define ESC_r CHAR_CR #endif /* We can't officially use ESC_t because it is a POSIX reserved identifier (presumably because of all the others like size_t). */ #ifndef ESC_tee #define ESC_tee CHAR_HT #endif /* Codes for different types of Unicode property */ #define PT_ANY 0 /* Any property - matches all chars */ #define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */ #define PT_GC 2 /* Specified general characteristic (e.g. L) */ #define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */ #define PT_SC 4 /* Script (e.g. Han) */ #define PT_ALNUM 5 /* Alphanumeric - the union of L and N */ #define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */ #define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ #define PT_WORD 8 /* Word - L plus N plus underscore */ /* Flag bits and data types for the extended class (OP_XCLASS) for classes that contain characters with values greater than 255. */ #define XCL_NOT 0x01 /* Flag: this is a negative class */ #define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ #define XCL_END 0 /* Marks end of individual items */ #define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ #define XCL_RANGE 2 /* A range (two multibyte chars) follows */ #define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ #define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ /* These are escaped items that aren't just an encoding of a particular data value such as \n. They must have non-zero values, as check_escape() returns their negation. Also, they must appear in the same order as in the opcode definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL mode rather than an escape sequence. It is also used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves like \N. The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. when PCRE_UCP is set, when replacement of \d etc by \p sequences is required. They must be contiguous, and remain in order so that the replacements can be looked up from a table. The final escape must be ESC_REF as subsequent values are used for backreferences (\1, \2, \3, etc). There are two tests in the code for an escape greater than ESC_b and less than ESC_Z to detect the types that may be repeated. These are the types that consume characters. If any new escapes are put in between that don't consume a character, that code will have to change. */ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_g, ESC_k, ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu, ESC_REF }; /* Opcode table: Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in order to the list of escapes immediately above. *** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions that follow must also be updated to match. There are also tables called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */ enum { OP_END, /* 0 End of pattern */ /* Values corresponding to backslashed metacharacters */ OP_SOD, /* 1 Start of data: \A */ OP_SOM, /* 2 Start of match (subject + offset): \G */ OP_SET_SOM, /* 3 Set start of match (\K) */ OP_NOT_WORD_BOUNDARY, /* 4 \B */ OP_WORD_BOUNDARY, /* 5 \b */ OP_NOT_DIGIT, /* 6 \D */ OP_DIGIT, /* 7 \d */ OP_NOT_WHITESPACE, /* 8 \S */ OP_WHITESPACE, /* 9 \s */ OP_NOT_WORDCHAR, /* 10 \W */ OP_WORDCHAR, /* 11 \w */ OP_ANY, /* 12 Match any character except newline */ OP_ALLANY, /* 13 Match any character */ OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */ OP_NOTPROP, /* 15 \P (not Unicode property) */ OP_PROP, /* 16 \p (Unicode property) */ OP_ANYNL, /* 17 \R (any newline sequence) */ OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */ OP_HSPACE, /* 19 \h (horizontal whitespace) */ OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */ OP_VSPACE, /* 21 \v (vertical whitespace) */ OP_EXTUNI, /* 22 \X (extended Unicode sequence */ OP_EODN, /* 23 End of data or \n at end of data: \Z. */ OP_EOD, /* 24 End of data: \z */ OP_CIRC, /* 25 Start of line - not multiline */ OP_CIRCM, /* 26 Start of line - multiline */ OP_DOLL, /* 27 End of line - not multiline */ OP_DOLLM, /* 28 End of line - multiline */ OP_CHAR, /* 29 Match one character, casefully */ OP_CHARI, /* 30 Match one character, caselessly */ OP_NOT, /* 31 Match one character, not the given one, casefully */ OP_NOTI, /* 32 Match one character, not the given one, caselessly */ /* The following sets of 13 opcodes must always be kept in step because the offset from the first one is used to generate the others. */ /**** Single characters, caseful, must precede the caseless ones ****/ OP_STAR, /* 33 The maximizing and minimizing versions of */ OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */ OP_PLUS, /* 35 the minimizing one second. */ OP_MINPLUS, /* 36 */ OP_QUERY, /* 37 */ OP_MINQUERY, /* 38 */ OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/ OP_MINUPTO, /* 40 */ OP_EXACT, /* 41 Exactly n matches */ OP_POSSTAR, /* 42 Possessified star, caseful */ OP_POSPLUS, /* 43 Possessified plus, caseful */ OP_POSQUERY, /* 44 Posesssified query, caseful */ OP_POSUPTO, /* 45 Possessified upto, caseful */ /**** Single characters, caseless, must follow the caseful ones */ OP_STARI, /* 46 */ OP_MINSTARI, /* 47 */ OP_PLUSI, /* 48 */ OP_MINPLUSI, /* 49 */ OP_QUERYI, /* 50 */ OP_MINQUERYI, /* 51 */ OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */ OP_MINUPTOI, /* 53 */ OP_EXACTI, /* 54 */ OP_POSSTARI, /* 55 Possessified star, caseless */ OP_POSPLUSI, /* 56 Possessified plus, caseless */ OP_POSQUERYI, /* 57 Posesssified query, caseless */ OP_POSUPTOI, /* 58 Possessified upto, caseless */ /**** The negated ones must follow the non-negated ones, and match them ****/ /**** Negated single character, caseful; must precede the caseless ones ****/ OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */ OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */ OP_NOTPLUS, /* 61 the minimizing one second. They must be in */ OP_NOTMINPLUS, /* 62 exactly the same order as those above. */ OP_NOTQUERY, /* 63 */ OP_NOTMINQUERY, /* 64 */ OP_NOTUPTO, /* 65 From 0 to n matches, caseful */ OP_NOTMINUPTO, /* 66 */ OP_NOTEXACT, /* 67 Exactly n matches */ OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */ OP_NOTPOSPLUS, /* 69 */ OP_NOTPOSQUERY, /* 70 */ OP_NOTPOSUPTO, /* 71 */ /**** Negated single character, caseless; must follow the caseful ones ****/ OP_NOTSTARI, /* 72 */ OP_NOTMINSTARI, /* 73 */ OP_NOTPLUSI, /* 74 */ OP_NOTMINPLUSI, /* 75 */ OP_NOTQUERYI, /* 76 */ OP_NOTMINQUERYI, /* 77 */ OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */ OP_NOTMINUPTOI, /* 79 */ OP_NOTEXACTI, /* 80 Exactly n matches */ OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */ OP_NOTPOSPLUSI, /* 82 */ OP_NOTPOSQUERYI, /* 83 */ OP_NOTPOSUPTOI, /* 84 */ /**** Character types ****/ OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */ OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */ OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */ OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */ OP_TYPEQUERY, /* 89 */ OP_TYPEMINQUERY, /* 90 */ OP_TYPEUPTO, /* 91 From 0 to n matches */ OP_TYPEMINUPTO, /* 92 */ OP_TYPEEXACT, /* 93 Exactly n matches */ OP_TYPEPOSSTAR, /* 94 Possessified versions */ OP_TYPEPOSPLUS, /* 95 */ OP_TYPEPOSQUERY, /* 96 */ OP_TYPEPOSUPTO, /* 97 */ /* These are used for character classes and back references; only the first six are the same as the sets above. */ OP_CRSTAR, /* 98 The maximizing and minimizing versions of */ OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */ OP_CRPLUS, /* 100 the minimizing one second. These codes must */ OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */ OP_CRQUERY, /* 102 */ OP_CRMINQUERY, /* 103 */ OP_CRRANGE, /* 104 These are different to the three sets above. */ OP_CRMINRANGE, /* 105 */ /* End of quantifier opcodes */ OP_CLASS, /* 106 Match a character class, chars < 256 only */ OP_NCLASS, /* 107 Same, but the bitmap was created from a negative class - the difference is relevant only when a character > 255 is encountered. */ OP_XCLASS, /* 108 Extended class for handling > 255 chars within the class. This does both positive and negative. */ OP_REF, /* 109 Match a back reference, casefully */ OP_REFI, /* 110 Match a back reference, caselessly */ OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */ OP_CALLOUT, /* 112 Call out to external function if provided */ OP_ALT, /* 113 Start of alternation */ OP_KET, /* 114 End of group that doesn't have an unbounded repeat */ OP_KETRMAX, /* 115 These two must remain together and in this */ OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */ OP_KETRPOS, /* 117 Possessive unlimited repeat. */ /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four asserts must remain in order. */ OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */ OP_ASSERT, /* 119 Positive lookahead */ OP_ASSERT_NOT, /* 120 Negative lookahead */ OP_ASSERTBACK, /* 121 Positive lookbehind */ OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */ /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. The POS versions must immediately follow the non-POS versions in each case. */ OP_ONCE, /* 123 Atomic group, contains captures */ OP_ONCE_NC, /* 124 Atomic group containing no captures */ OP_BRA, /* 125 Start of non-capturing bracket */ OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */ OP_CBRA, /* 127 Start of capturing bracket */ OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */ OP_COND, /* 129 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ OP_SBRA, /* 130 Start of non-capturing bracket, check empty */ OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */ OP_SCBRA, /* 132 Start of capturing bracket, check empty */ OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ OP_SCOND, /* 134 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ OP_CREF, /* 135 Used to hold a capture number as condition */ OP_NCREF, /* 136 Same, but generated by a name reference*/ OP_RREF, /* 137 Used to hold a recursion number as condition */ OP_NRREF, /* 138 Same, but generated by a name reference*/ OP_DEF, /* 139 The DEFINE condition */ OP_BRAZERO, /* 140 These two must remain together and in this */ OP_BRAMINZERO, /* 141 order. */ OP_BRAPOSZERO, /* 142 */ /* These are backtracking control verbs */ OP_MARK, /* 143 always has an argument */ OP_PRUNE, /* 144 */ OP_PRUNE_ARG, /* 145 same, but with argument */ OP_SKIP, /* 146 */ OP_SKIP_ARG, /* 147 same, but with argument */ OP_THEN, /* 148 */ OP_THEN_ARG, /* 149 same, but with argument */ OP_COMMIT, /* 150 */ /* These are forced failure and success verbs */ OP_FAIL, /* 151 */ OP_ACCEPT, /* 152 */ OP_ASSERT_ACCEPT, /* 153 Used inside assertions */ OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ OP_SKIPZERO, /* 155 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been some in the past. */ OP_TABLE_LENGTH }; /* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro definitions that follow must also be updated to match. There are also tables called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */ /* This macro defines textual names for all the opcodes. These are used only for debugging, and some of them are only partial names. The macro is referenced only in pcre_printint.c, which fills out the full names in many cases (and in some cases doesn't actually use these names at all). */ #define OP_NAME_LIST \ "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \ "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \ "extuni", "\\Z", "\\z", \ "^", "^", "$", "$", "char", "chari", "not", "noti", \ "*", "*?", "+", "+?", "?", "??", \ "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", \ "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", \ "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", \ "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ "class", "nclass", "xclass", "Ref", "Refi", \ "Recurse", "Callout", \ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ "Once", "Once_NC", \ "Bra", "BraPos", "CBra", "CBraPos", \ "Cond", \ "SBra", "SBraPos", "SCBra", "SCBraPos", \ "SCond", \ "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \ "Brazero", "Braminzero", "Braposzero", \ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ "*THEN", "*THEN", "*COMMIT", "*FAIL", \ "*ACCEPT", "*ASSERT_ACCEPT", \ "Close", "Skip zero" /* This macro defines the length of fixed length operations in the compiled regex. The lengths are used when searching for specific things, and also in the debugging printing of a compiled regex. We use a macro so that it can be defined close to the definitions of the opcodes themselves. As things have been extended, some of these are no longer fixed lenths, but are minima instead. For example, the length of a single-character repeat may vary in UTF-8 mode. The code that uses this table must know about such things. */ #define OP_LENGTHS \ 1, /* End */ \ 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \ 1, 1, 1, /* Any, AllAny, Anybyte */ \ 3, 3, /* \P, \p */ \ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \ 1, /* \X */ \ 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \ 2, /* Char - the minimum length */ \ 2, /* Chari - the minimum length */ \ 2, /* not */ \ 2, /* noti */ \ /* Positive single-char repeats ** These are */ \ 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \ 2+IMM2_SIZE, /* exact */ \ 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \ 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \ 2+IMM2_SIZE, /* exact I */ \ 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \ /* Negative single-char repeats - only for chars < 256 */ \ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \ 2+IMM2_SIZE, /* NOT exact */ \ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \ 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \ 2+IMM2_SIZE, /* NOT exact I */ \ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \ /* Positive type repeats */ \ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \ 2+IMM2_SIZE, /* Type exact */ \ 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \ /* Character class & ref repeats */ \ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \ 1+(32/sizeof(pcre_uchar)), /* CLASS */ \ 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \ 0, /* XCLASS - variable length */ \ 1+IMM2_SIZE, /* REF */ \ 1+IMM2_SIZE, /* REFI */ \ 1+LINK_SIZE, /* RECURSE */ \ 2+2*LINK_SIZE, /* CALLOUT */ \ 1+LINK_SIZE, /* Alt */ \ 1+LINK_SIZE, /* Ket */ \ 1+LINK_SIZE, /* KetRmax */ \ 1+LINK_SIZE, /* KetRmin */ \ 1+LINK_SIZE, /* KetRpos */ \ 1+LINK_SIZE, /* Reverse */ \ 1+LINK_SIZE, /* Assert */ \ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ 1+LINK_SIZE, /* Assert behind not */ \ 1+LINK_SIZE, /* ONCE */ \ 1+LINK_SIZE, /* ONCE_NC */ \ 1+LINK_SIZE, /* BRA */ \ 1+LINK_SIZE, /* BRAPOS */ \ 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \ 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \ 1+LINK_SIZE, /* COND */ \ 1+LINK_SIZE, /* SBRA */ \ 1+LINK_SIZE, /* SBRAPOS */ \ 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \ 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \ 1+LINK_SIZE, /* SCOND */ \ 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \ 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \ 1, /* DEF */ \ 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ 1, 3, /* SKIP, SKIP_ARG */ \ 1, 3, /* THEN, THEN_ARG */ \ 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \ 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */ /* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion" condition. */ #define RREF_ANY 0xffff /* Compile time error code numbers. They are given names so that they can more easily be tracked. When a new number is added, the table called eint in pcreposix.c must be updated. */ 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, ERR48, ERR49, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERRCOUNT }; /* JIT compiling modes. The function list is indexed by them. */ enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE, JIT_NUMBER_OF_COMPILE_MODES }; /* 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 offset to the name table so that if a regex is compiled on one host, saved, and then run on another where the size of pointers is different, all might still be well. For the case of compiled-on-4 and run-on-8, we include an extra pointer that is always NULL. For future-proofing, a few dummy fields were originally included - even though you can never get this planning right - but there is only one left now. NOTE NOTE NOTE: Because people can now save and re-use compiled patterns, any additions to this structure should be made at the end, and something earlier (e.g. a new flag in the options or one of the dummy fields) should indicate that the new fields are present. Currently PCRE always sets the dummy fields to zero. NOTE NOTE NOTE */ #ifdef COMPILE_PCRE8 #define REAL_PCRE real_pcre #else #define REAL_PCRE real_pcre16 #endif typedef struct REAL_PCRE { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; /* Public options */ pcre_uint16 flags; /* Private flags */ pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */ pcre_uint16 top_bracket; /* Highest numbered group */ pcre_uint16 top_backref; /* Highest numbered back reference */ pcre_uint16 first_char; /* Starting character */ pcre_uint16 req_char; /* This character must be seen */ pcre_uint16 name_table_offset; /* Offset to name table that follows */ pcre_uint16 name_entry_size; /* Size of any name items */ pcre_uint16 name_count; /* Number of name items */ pcre_uint16 ref_count; /* Reference count */ const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ const pcre_uint8 *nullpad; /* NULL padding */ } REAL_PCRE; /* The format of the block used to store data from pcre_study(). The same remark (see NOTE above) about extending this structure applies. */ typedef struct pcre_study_data { pcre_uint32 size; /* Total that was malloced */ pcre_uint32 flags; /* Private flags */ pcre_uint8 start_bits[32]; /* Starting char bits */ pcre_uint32 minlength; /* Minimum subject length */ } pcre_study_data; /* Structure for building a chain of open capturing subpatterns during compiling, so that instructions to close them can be compiled when (*ACCEPT) is encountered. This is also used to identify subpatterns that contain recursive back references to themselves, so that they can be made atomic. */ typedef struct open_capitem { struct open_capitem *next; /* Chain link */ pcre_uint16 number; /* Capture number */ pcre_uint16 flag; /* Set TRUE if recursive back ref */ } open_capitem; /* Structure for passing "static" information around between the functions doing the compiling, so that they are thread-safe. */ typedef struct compile_data { const pcre_uint8 *lcc; /* Points to lower casing table */ const pcre_uint8 *fcc; /* Points to case-flipping table */ const pcre_uint8 *cbits; /* Points to character type table */ const pcre_uint8 *ctypes; /* Points to table of type maps */ const pcre_uchar *start_workspace;/* The start of working space */ const pcre_uchar *start_code; /* The start of the compiled code */ const pcre_uchar *start_pattern; /* The start of the pattern */ const pcre_uchar *end_pattern; /* The end of the pattern */ open_capitem *open_caps; /* Chain of open capture items */ pcre_uchar *hwm; /* High watermark of workspace */ pcre_uchar *name_table; /* The name/number table */ int names_found; /* Number of entries so far */ int name_entry_size; /* Size of each entry */ int workspace_size; /* Size of workspace */ int bracount; /* Count of capturing parens as we compile */ int final_bracount; /* Saved value after first pass */ int max_lookbehind; /* Maximum lookbehind (characters) */ int top_backref; /* Maximum back reference */ unsigned int backref_map; /* Bitmap of low back refs */ int assert_depth; /* Depth of nested assertions */ int external_options; /* External (initial) options */ int external_flags; /* External flag bits to be set */ int req_varyopt; /* "After variable item" flag for reqbyte */ BOOL had_accept; /* (*ACCEPT) encountered */ BOOL check_lookbehind; /* Lookbehinds need later checking */ int nltype; /* Newline type */ int nllen; /* Newline string length */ pcre_uchar nl[4]; /* Newline string when fixed length */ } compile_data; /* Structure for maintaining a chain of pointers to the currently incomplete branches, for testing for left recursion while compiling. */ typedef struct branch_chain { struct branch_chain *outer; pcre_uchar *current_branch; } branch_chain; /* Structure for items in a linked list that represents an explicit recursive call within the pattern; used by pcre_exec(). */ typedef struct recursion_info { struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ int group_num; /* Number of group that was called */ int *offset_save; /* Pointer to start of saved offsets */ int saved_max; /* Number of saved offsets */ PCRE_PUCHAR subject_position; /* Position at start of recursion */ } recursion_info; /* A similar structure for pcre_dfa_exec(). */ typedef struct dfa_recursion_info { struct dfa_recursion_info *prevrec; int group_num; PCRE_PUCHAR subject_position; } dfa_recursion_info; /* Structure for building a chain of data 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; used by pcre_exec(). */ typedef struct eptrblock { struct eptrblock *epb_prev; PCRE_PUCHAR epb_saved_eptr; } eptrblock; /* Structure for passing "static" information around between the functions doing traditional NFA matching, so that they are thread-safe. */ typedef struct match_data { unsigned long int match_call_count; /* As it says */ unsigned long int match_limit; /* As it says */ unsigned long int match_limit_recursion; /* As it says */ int *offset_vector; /* Offset vector */ int offset_end; /* One past the end */ int offset_max; /* The maximum usable for return data */ int nltype; /* Newline type */ int nllen; /* Newline string length */ int name_count; /* Number of names in name table */ int name_entry_size; /* Size of entry in names table */ pcre_uchar *name_table; /* Table of names */ pcre_uchar nl[4]; /* Newline string when fixed */ const pcre_uint8 *lcc; /* Points to lower casing table */ const pcre_uint8 *fcc; /* Points to case-flipping table */ const pcre_uint8 *ctypes; /* Points to table of type maps */ BOOL offset_overflow; /* Set if too many extractions */ BOOL notbol; /* NOTBOL flag */ BOOL noteol; /* NOTEOL flag */ BOOL utf; /* UTF-8 / UTF-16 flag */ BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */ BOOL use_ucp; /* PCRE_UCP flag */ BOOL endonly; /* Dollar not before final \n */ BOOL notempty; /* Empty string match not wanted */ BOOL notempty_atstart; /* Empty string match at start not wanted */ BOOL hitend; /* Hit the end of the subject at some point */ BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */ BOOL hasthen; /* Pattern contains (*THEN) */ BOOL ignore_skip_arg; /* For re-run when SKIP name not found */ const pcre_uchar *start_code; /* For use when recursing */ PCRE_PUCHAR start_subject; /* Start of the subject string */ PCRE_PUCHAR end_subject; /* End of the subject string */ PCRE_PUCHAR start_match_ptr; /* Start of matched string */ PCRE_PUCHAR end_match_ptr; /* Subject position at end match */ PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */ int partial; /* PARTIAL options */ int end_offset_top; /* Highwater mark at end of match */ int capture_last; /* Most recent capture number */ int start_offset; /* The start offset value */ int match_function_type; /* Set for certain special calls of MATCH() */ eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ int eptrn; /* Next free eptrblock */ recursion_info *recursive; /* Linked list of recursion data */ void *callout_data; /* To pass back to callouts */ const pcre_uchar *mark; /* Mark pointer to pass back on success */ const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */ const pcre_uchar *once_target; /* Where to back up to for atomic groups */ #ifdef NO_RECURSE void *match_frames_base; /* For remembering malloc'd frames */ #endif } match_data; /* A similar structure is used for the same purpose by the DFA matching functions. */ typedef struct dfa_match_data { const pcre_uchar *start_code; /* Start of the compiled pattern */ const pcre_uchar *start_subject ; /* Start of the subject string */ const pcre_uchar *end_subject; /* End of subject string */ const pcre_uchar *start_used_ptr; /* Earliest consulted character */ const pcre_uint8 *tables; /* Character tables */ int start_offset; /* The start offset value */ int moptions; /* Match options */ int poptions; /* Pattern options */ int nltype; /* Newline type */ int nllen; /* Newline string length */ pcre_uchar nl[4]; /* Newline string when fixed */ void *callout_data; /* To pass back to callouts */ dfa_recursion_info *recursive; /* Linked list of recursion data */ } dfa_match_data; /* Bit definitions for entries in the pcre_ctypes table. */ #define ctype_space 0x01 #define ctype_letter 0x02 #define ctype_digit 0x04 #define ctype_xdigit 0x08 #define ctype_word 0x10 /* alphanumeric or '_' */ #define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ /* Offsets for the bitmap tables in pcre_cbits. Each table contains a set of bits for a class map. Some classes are built by combining these tables. */ #define cbit_space 0 /* [:space:] or \s */ #define cbit_xdigit 32 /* [:xdigit:] */ #define cbit_digit 64 /* [:digit:] or \d */ #define cbit_upper 96 /* [:upper:] */ #define cbit_lower 128 /* [:lower:] */ #define cbit_word 160 /* [:word:] or \w */ #define cbit_graph 192 /* [:graph:] */ #define cbit_print 224 /* [:print:] */ #define cbit_punct 256 /* [:punct:] */ #define cbit_cntrl 288 /* [:cntrl:] */ #define cbit_length 320 /* Length of the cbits table */ /* Offsets of the various tables from the base tables pointer, and total length. */ #define lcc_offset 0 #define fcc_offset 256 #define cbits_offset 512 #define ctypes_offset (cbits_offset + cbit_length) #define tables_length (ctypes_offset + 256) /* Internal function and data prefixes. */ #ifdef COMPILE_PCRE8 #ifndef PUBL #define PUBL(name) pcre_##name #endif #ifndef PRIV #define PRIV(name) _pcre_##name #endif #else /* COMPILE_PCRE8 */ #ifdef COMPILE_PCRE16 #ifndef PUBL #define PUBL(name) pcre16_##name #endif #ifndef PRIV #define PRIV(name) _pcre16_##name #endif #else #error Unsupported compiling mode #endif /* COMPILE_PCRE16 */ #endif /* COMPILE_PCRE8 */ /* Layout of the UCP type table that translates property names into types and codes. Each entry used to point directly to a name, but to reduce the number of relocations in shared libraries, it now has an offset into a single string instead. */ typedef struct { pcre_uint16 name_offset; pcre_uint16 type; pcre_uint16 value; } ucp_type_table; /* Internal shared data tables. These are tables that are used by more than one of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. The data for these tables is in the pcre_tables.c module. */ #ifdef COMPILE_PCRE8 extern const int PRIV(utf8_table1)[]; extern const int PRIV(utf8_table1_size); extern const int PRIV(utf8_table2)[]; extern const int PRIV(utf8_table3)[]; extern const pcre_uint8 PRIV(utf8_table4)[]; #endif /* COMPILE_PCRE8 */ extern const char PRIV(utt_names)[]; extern const ucp_type_table PRIV(utt)[]; extern const int PRIV(utt_size); extern const pcre_uint8 PRIV(default_tables)[]; extern const pcre_uint8 PRIV(OP_lengths)[]; /* Internal shared functions. These are functions that are used by more than one of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. */ /* String comparison functions. */ #ifdef COMPILE_PCRE8 #define STRCMP_UC_UC(str1, str2) \ strcmp((char *)(str1), (char *)(str2)) #define STRCMP_UC_C8(str1, str2) \ strcmp((char *)(str1), (str2)) #define STRNCMP_UC_UC(str1, str2, num) \ strncmp((char *)(str1), (char *)(str2), (num)) #define STRNCMP_UC_C8(str1, str2, num) \ strncmp((char *)(str1), (str2), (num)) #define STRLEN_UC(str) strlen((const char *)str) #else extern int PRIV(strcmp_uc_uc)(const pcre_uchar *, const pcre_uchar *); extern int PRIV(strcmp_uc_c8)(const pcre_uchar *, const char *); extern int PRIV(strncmp_uc_uc)(const pcre_uchar *, const pcre_uchar *, unsigned int num); extern int PRIV(strncmp_uc_c8)(const pcre_uchar *, const char *, unsigned int num); extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str); #define STRCMP_UC_UC(str1, str2) \ PRIV(strcmp_uc_uc)((str1), (str2)) #define STRCMP_UC_C8(str1, str2) \ PRIV(strcmp_uc_c8)((str1), (str2)) #define STRNCMP_UC_UC(str1, str2, num) \ PRIV(strncmp_uc_uc)((str1), (str2), (num)) #define STRNCMP_UC_C8(str1, str2, num) \ PRIV(strncmp_uc_c8)((str1), (str2), (num)) #define STRLEN_UC(str) PRIV(strlen_uc)(str) #endif /* COMPILE_PCRE8 */ extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int); extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, int *, BOOL); extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *); extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *); extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, int *, BOOL); extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL); #ifdef SUPPORT_JIT extern void PRIV(jit_compile)(const REAL_PCRE *, PUBL(extra) *, int); extern int PRIV(jit_exec)(const REAL_PCRE *, const PUBL(extra) *, const pcre_uchar *, int, int, int, int *, int); extern void PRIV(jit_free)(void *); extern int PRIV(jit_get_size)(void *); extern const char* PRIV(jit_get_target)(void); #endif /* Unicode character database (UCD) */ typedef struct { pcre_uint8 script; pcre_uint8 chartype; pcre_int32 other_case; } ucd_record; extern const ucd_record PRIV(ucd_records)[]; extern const pcre_uint8 PRIV(ucd_stage1)[]; extern const pcre_uint16 PRIV(ucd_stage2)[]; extern const int PRIV(ucp_gentype)[]; #ifdef SUPPORT_JIT extern const int PRIV(ucp_typerange)[]; #endif #ifdef SUPPORT_UCP /* UCD access macros */ #define UCD_BLOCK_SIZE 128 #define GET_UCD(ch) (PRIV(ucd_records) + \ PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \ UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE]) #define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype #define UCD_SCRIPT(ch) GET_UCD(ch)->script #define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] #define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case) #endif /* SUPPORT_UCP */ #endif /* End of pcre_internal.h */ pcre-8.31/pcre16_maketables.c0000644000222100022210000000420711676645217012761 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_maketables.c" /* End of pcre16_maketables.c */ pcre-8.31/config.h.in0000644000222100022210000002606011775524613011345 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, so that config.h is included at the start of every source. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* By default, the \R escape sequence matches any Unicode line ending character or sequence of characters. If BSR_ANYCRLF is defined, this is changed so that backslash-R matches only CR, LF, or CRLF. The build- time default can be overridden by the user of PCRE at runtime. On systems that support it, "configure" can be used to override the default. */ #undef BSR_ANYCRLF /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. PCRE will then assume that all input strings are in EBCDIC. If you do not define this macro, PCRE will assume input strings are ASCII or UTF-8/16 Unicode. It is not possible to build a version of PCRE that supports both EBCDIC and UTF-8/16. */ #undef EBCDIC /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY /* Define to 1 if you have the header file. */ #undef HAVE_BITS_TYPE_TRAITS_H /* Define to 1 if you have the header file. */ #undef HAVE_BZLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_EDITLINE_READLINE_H /* Define to 1 if you have the header file. */ #undef HAVE_EDIT_READLINE_READLINE_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if the system has the type `long long'. */ #undef HAVE_LONG_LONG /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_HISTORY_H /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_READLINE_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRING /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have `strtoimax'. */ #undef HAVE_STRTOIMAX /* Define to 1 if you have `strtoll'. */ #undef HAVE_STRTOLL /* Define to 1 if you have `strtoq'. */ #undef HAVE_STRTOQ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_TYPE_TRAITS_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `unsigned long long'. */ #undef HAVE_UNSIGNED_LONG_LONG /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* Define to 1 if you have the header file. */ #undef HAVE_ZLIB_H /* Define to 1 if you have `_strtoi64'. */ #undef HAVE__STRTOI64 /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default. */ #undef LINK_SIZE /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default. */ #undef MATCH_LIMIT /* The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default. */ #undef MATCH_LIMIT_RECURSION /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #undef MAX_NAME_COUNT /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #undef MAX_NAME_SIZE /* The value of NEWLINE determines the newline character sequence. On systems that support it, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF). */ #undef NEWLINE /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ #undef NO_RECURSE /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The value of PCREGREP_BUFSIZE determines the size of buffer used by pcregrep to hold parts of the file it is searching. On systems that support it, "configure" can be used to override the default, which is 8192. This is also the minimum value. The actual amount of memory used by pcregrep is three times this number, because it allows for the buffering of "before" and "after" lines. */ #undef PCREGREP_BUFSIZE /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ #undef PCRE_EXP_DEFN /* Define if linking statically (TODO: make nice with Libtool) */ #undef PCRE_STATIC /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default. */ #undef POSIX_MALLOC_THRESHOLD /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to enable support for Just-In-Time compiling. */ #undef SUPPORT_JIT /* Define to allow pcregrep to be linked with libbz2, so that it is able to handle .bz2 files. */ #undef SUPPORT_LIBBZ2 /* Define to allow pcretest to be linked with libedit. */ #undef SUPPORT_LIBEDIT /* Define to allow pcretest to be linked with libreadline. */ #undef SUPPORT_LIBREADLINE /* Define to allow pcregrep to be linked with libz, so that it is able to handle .gz files. */ #undef SUPPORT_LIBZ /* Define to enable the 16 bit PCRE library. */ #undef SUPPORT_PCRE16 /* Define to enable the 8 bit PCRE library. */ #undef SUPPORT_PCRE8 /* Define to enable JIT support in pcregrep. */ #undef SUPPORT_PCREGREP_JIT /* Define to enable support for Unicode properties. */ #undef SUPPORT_UCP /* Define to enable support for the UTF-8/16 Unicode encoding. This will work even in an EBCDIC environment, but it is incompatible with the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8/16, but not both at once. */ #undef SUPPORT_UTF /* Version number of package */ #undef VERSION /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to the type of a signed integer type of width exactly 64 bits if such a type exists and the standard includes do not define it. */ #undef int64_t /* Define to `unsigned int' if does not define. */ #undef size_t pcre-8.31/pcre16_tables.c0000644000222100022210000000417711676645216012130 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_tables.c" /* End of pcre16_tables.c */ pcre-8.31/pcre16_chartables.c0000644000222100022210000000420711676645227012762 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_chartables.c" /* End of pcre16_chartables.c */ pcre-8.31/CleanTxt0000755000222100022210000000557510573766503011003 00000000000000#! /usr/bin/perl -w # Script to take the output of nroff -man and remove all the backspacing and # the page footers and the screen commands etc so that it is more usefully # readable online. In fact, in the latest nroff, intermediate footers don't # seem to be generated any more. $blankcount = 0; $lastwascut = 0; $firstheader = 1; # Input on STDIN; output to STDOUT. while () { s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" s/.\x8//g; # Remove "char, backspace" # Handle header lines. Retain only the first one we encounter, but remove # the blank line that follows. Any others (e.g. at end of document) and the # following blank line are dropped. if (/^PCRE(\w*)\(([13])\)\s+PCRE\1\(\2\)$/) { if ($firstheader) { $firstheader = 0; print; $lastprinted = $_; $lastwascut = 0; } $_=; # Remove a blank that follows next; } # Count runs of empty lines if (/^\s*$/) { $blankcount++; $lastwascut = 0; next; } # If a chunk of lines has been cut out (page footer) and the next line # has a different indentation, put back one blank line. if ($lastwascut && $blankcount < 1 && defined($lastprinted)) { ($a) = $lastprinted =~ /^(\s*)/; ($b) = $_ =~ /^(\s*)/; $blankcount++ if ($a ne $b); } # We get here only when we have a non-blank line in hand. If it was preceded # by 3 or more blank lines, read the next 3 lines and see if they are blank. # If so, remove all 7 lines, and remember that we have just done a cut. if ($blankcount >= 3) { for ($i = 0; $i < 3; $i++) { $next[$i] = ; $next[$i] = "" if !defined $next[$i]; $next[$i] =~ s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" $next[$i] =~ s/.\x8//g; # Remove "char, backspace" } # Cut out chunks of the form <3 blanks><3 blanks> if ($next[0] =~ /^\s*$/ && $next[1] =~ /^\s*$/ && $next[2] =~ /^\s*$/) { $blankcount -= 3; $lastwascut = 1; } # Otherwise output the saved blanks, the current, and the next three # lines. Remember the last printed line. else { for ($i = 0; $i < $blankcount; $i++) { print "\n"; } print; for ($i = 0; $i < 3; $i++) { $next[$i] =~ s/.\x8//g; print $next[$i]; $lastprinted = $_; } $lastwascut = 0; $blankcount = 0; } } # This non-blank line is not preceded by 3 or more blank lines. Output # any blanks there are, and the line. Remember it. Force two blank lines # before headings. else { $blankcount = 2 if /^\S/ && !/^Last updated/ && !/^Copyright/ && defined($lastprinted); for ($i = 0; $i < $blankcount; $i++) { print "\n"; } print; $lastprinted = $_; $lastwascut = 0; $blankcount = 0; } } # End pcre-8.31/pcre16_fullinfo.c0000644000222100022210000000420311676645224012461 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_fullinfo.c" /* End of pcre16_fullinfo.c */ pcre-8.31/pcre_compile.c0000644000222100022210000101667411770363602012134 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_compile(), along with supporting internal functions that are not used by other modules. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define NLBLOCK cd /* Block containing newline information */ #define PSSTART start_pattern /* Field containing processed string start */ #define PSEND end_pattern /* Field containing processed string end */ #include "pcre_internal.h" /* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which is also used by pcretest. PCRE_DEBUG is not defined when building a production library. We do not need to select pcre16_printint.c specially, because the COMPILE_PCREx macro will already be appropriately set. */ #ifdef PCRE_DEBUG /* pcre_printint.c should not include any headers */ #define PCRE_INCLUDED #include "pcre_printint.c" #undef PCRE_INCLUDED #endif /* Macro for setting individual bits in class bitmaps. */ #define SETBIT(a,b) a[b/8] |= (1 << (b%8)) /* Maximum length value to check against when making sure that the integer that holds the compiled pattern length does not overflow. We make it a bit less than INT_MAX to allow for adding in group terminating bytes, so that we don't have to check them every time. */ #define OFLOW_MAX (INT_MAX - 20) /************************************************* * Code parameters and static tables * *************************************************/ /* This value specifies the size of stack workspace that is used during the first pre-compile phase that determines how much memory is required. The regex is partly compiled into this space, but the compiled parts are discarded as soon as they can be, so that hopefully there will never be an overrun. The code does, however, check for an overrun. The largest amount I've seen used is 218, so this number is very generous. The same workspace is used during the second, actual compile phase for remembering forward references to groups so that they can be filled in at the end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE is 4 there is plenty of room for most patterns. However, the memory can get filled up by repetitions of forward references, for example patterns like /(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so that the workspace is expanded using malloc() in this situation. The value below is therefore a minimum, and we put a maximum on it for safety. The minimum is now also defined in terms of LINK_SIZE so that the use of malloc() kicks in at the same number of forward references in all cases. */ #define COMPILE_WORK_SIZE (2048*LINK_SIZE) #define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE) /* The overrun tests check for a slightly smaller size so that they detect the overrun before it actually does run off the end of the data block. */ #define WORK_SIZE_SAFETY_MARGIN (100) /* Private flags added to firstchar and reqchar. */ #define REQ_CASELESS 0x10000000l /* Indicates caselessness */ #define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */ /* Repeated character flags. */ #define UTF_LENGTH 0x10000000l /* The char contains its length. */ /* Table for handling escaped characters in the range '0'-'z'. Positive returns are simple data values; negative values are for special things like \d and so on. Zero means further processing is needed (for things like \x), or the escape is invalid. */ #ifndef EBCDIC /* This is the "normal" table for ASCII systems or for EBCDIC systems running in UTF-8 mode. */ static const short int escapes[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAR_COLON, CHAR_SEMICOLON, CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK, CHAR_COMMERCIAL_AT, -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G, -ESC_H, 0, 0, -ESC_K, 0, 0, -ESC_N, 0, -ESC_P, -ESC_Q, -ESC_R, -ESC_S, 0, 0, -ESC_V, -ESC_W, -ESC_X, 0, -ESC_Z, CHAR_LEFT_SQUARE_BRACKET, CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET, CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE, CHAR_GRAVE_ACCENT, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, -ESC_h, 0, 0, -ESC_k, 0, 0, ESC_n, 0, -ESC_p, 0, ESC_r, -ESC_s, ESC_tee, 0, -ESC_v, -ESC_w, 0, 0, -ESC_z }; #else /* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */ static const short int escapes[] = { /* 48 */ 0, 0, 0, '.', '<', '(', '+', '|', /* 50 */ '&', 0, 0, 0, 0, 0, 0, 0, /* 58 */ 0, 0, '!', '$', '*', ')', ';', '~', /* 60 */ '-', '/', 0, 0, 0, 0, 0, 0, /* 68 */ 0, 0, '|', ',', '%', '_', '>', '?', /* 70 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"', /* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0, /* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p, /* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0, /* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0, /* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0, /* B0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* B8 */ 0, 0, 0, 0, 0, ']', '=', '-', /* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G, /* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0, /* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P, /* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0, /* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X, /* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0, /* F0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* F8 */ 0, 0, 0, 0, 0, 0, 0, 0 }; #endif /* Table of special "verbs" like (*PRUNE). This is a short table, so it is searched linearly. Put all the names into a single string, in order to reduce the number of relocations when a shared library is dynamically linked. The string is built from string macros so that it works in UTF-8 mode on EBCDIC platforms. */ typedef struct verbitem { int len; /* Length of verb name */ int op; /* Op when no arg, or -1 if arg mandatory */ int op_arg; /* Op when arg present, or -1 if not allowed */ } verbitem; static const char verbnames[] = "\0" /* Empty name is a shorthand for MARK */ STRING_MARK0 STRING_ACCEPT0 STRING_COMMIT0 STRING_F0 STRING_FAIL0 STRING_PRUNE0 STRING_SKIP0 STRING_THEN; static const verbitem verbs[] = { { 0, -1, OP_MARK }, { 4, -1, OP_MARK }, { 6, OP_ACCEPT, -1 }, { 6, OP_COMMIT, -1 }, { 1, OP_FAIL, -1 }, { 4, OP_FAIL, -1 }, { 5, OP_PRUNE, OP_PRUNE_ARG }, { 4, OP_SKIP, OP_SKIP_ARG }, { 4, OP_THEN, OP_THEN_ARG } }; static const int verbcount = sizeof(verbs)/sizeof(verbitem); /* Tables of names of POSIX character classes and their lengths. The names are now all in a single string, to reduce the number of relocations when a shared library is dynamically loaded. The list of lengths is terminated by a zero length entry. The first three must be alpha, lower, upper, as this is assumed for handling case independence. */ static const char posix_names[] = STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0 STRING_graph0 STRING_print0 STRING_punct0 STRING_space0 STRING_word0 STRING_xdigit; static const pcre_uint8 posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; /* Table of class bit maps for each POSIX class. Each class is formed from a base map, with an optional addition or removal of another map. Then, for some classes, there is some additional tweaking: for [:blank:] the vertical space characters are removed, and for [:alpha:] and [:alnum:] the underscore character is removed. The triples in the table consist of the base map offset, second map offset or -1 if no second map, and a non-negative value for map addition or a negative value for map subtraction (if there are two maps). The absolute value of the third field has these meanings: 0 => no tweaking, 1 => remove vertical space characters, 2 => remove underscore. */ static const int posix_class_maps[] = { cbit_word, cbit_digit, -2, /* alpha */ cbit_lower, -1, 0, /* lower */ cbit_upper, -1, 0, /* upper */ cbit_word, -1, 2, /* alnum - word without underscore */ cbit_print, cbit_cntrl, 0, /* ascii */ cbit_space, -1, 1, /* blank - a GNU extension */ cbit_cntrl, -1, 0, /* cntrl */ cbit_digit, -1, 0, /* digit */ cbit_graph, -1, 0, /* graph */ cbit_print, -1, 0, /* print */ cbit_punct, -1, 0, /* punct */ cbit_space, -1, 0, /* space */ cbit_word, -1, 0, /* word - a Perl extension */ cbit_xdigit,-1, 0 /* xdigit */ }; /* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class substitutes must be in the order of the names, defined above, and there are both positive and negative cases. NULL means no substitute. */ #ifdef SUPPORT_UCP static const pcre_uchar string_PNd[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_pNd[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_PXsp[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_pXsp[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_PXwd[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_pXwd[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar *substitutes[] = { string_PNd, /* \D */ string_pNd, /* \d */ string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */ string_pXsp, /* \s */ string_PXwd, /* \W */ string_pXwd /* \w */ }; static const pcre_uchar string_pL[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_pLl[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_pLu[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_pXan[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_h[] = { CHAR_BACKSLASH, CHAR_h, '\0' }; static const pcre_uchar string_pXps[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_PL[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_PLl[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_PLu[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_PXan[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar string_H[] = { CHAR_BACKSLASH, CHAR_H, '\0' }; static const pcre_uchar string_PXps[] = { CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; static const pcre_uchar *posix_substitutes[] = { string_pL, /* alpha */ string_pLl, /* lower */ string_pLu, /* upper */ string_pXan, /* alnum */ NULL, /* ascii */ string_h, /* blank */ NULL, /* cntrl */ string_pNd, /* digit */ NULL, /* graph */ NULL, /* print */ NULL, /* punct */ string_pXps, /* space */ /* NOTE: Xps is POSIX space */ string_pXwd, /* word */ NULL, /* xdigit */ /* Negated cases */ string_PL, /* ^alpha */ string_PLl, /* ^lower */ string_PLu, /* ^upper */ string_PXan, /* ^alnum */ NULL, /* ^ascii */ string_H, /* ^blank */ NULL, /* ^cntrl */ string_PNd, /* ^digit */ NULL, /* ^graph */ NULL, /* ^print */ NULL, /* ^punct */ string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */ string_PXwd, /* ^word */ NULL /* ^xdigit */ }; #define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *)) #endif #define STRING(a) # a #define XSTRING(s) STRING(s) /* The texts of compile-time error messages. These are "char *" because they are passed to the outside world. Do not ever re-use any error number, because they are documented. Always add a new error instead. Messages marked DEAD below are no longer used. This used to be a table of strings, but in order to reduce the number of relocations needed when a shared library is loaded dynamically, it is now one long string. We cannot use a table of offsets, because the lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we simply count through to the one we want - this isn't a performance issue because these strings are used only when there is a compilation error. Each substring ends with \0 to insert a null character. This includes the final substring, so that the whole string ends with \0\0, which can be detected when counting through. */ static const char error_texts[] = "no error\0" "\\ at end of pattern\0" "\\c at end of pattern\0" "unrecognized character follows \\\0" "numbers out of order in {} quantifier\0" /* 5 */ "number too big in {} quantifier\0" "missing terminating ] for character class\0" "invalid escape sequence in character class\0" "range out of order in character class\0" "nothing to repeat\0" /* 10 */ "operand of unlimited repeat could match the empty string\0" /** DEAD **/ "internal error: unexpected repeat\0" "unrecognized character after (? or (?-\0" "POSIX named classes are supported only within a class\0" "missing )\0" /* 15 */ "reference to non-existent subpattern\0" "erroffset passed as NULL\0" "unknown option bit(s) set\0" "missing ) after comment\0" "parentheses nested too deeply\0" /** DEAD **/ /* 20 */ "regular expression is too large\0" "failed to get memory\0" "unmatched parentheses\0" "internal error: code overflow\0" "unrecognized character after (?<\0" /* 25 */ "lookbehind assertion is not fixed length\0" "malformed number or name after (?(\0" "conditional group contains more than two branches\0" "assertion expected after (?(\0" "(?R or (?[+-]digits must be followed by )\0" /* 30 */ "unknown POSIX class name\0" "POSIX collating elements are not supported\0" "this version of PCRE is compiled without UTF support\0" "spare error\0" /** DEAD **/ "character value in \\x{...} sequence is too large\0" /* 35 */ "invalid condition (?(0)\0" "\\C not allowed in lookbehind assertion\0" "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0" "number after (?C is > 255\0" "closing ) for (?C expected\0" /* 40 */ "recursive call could loop indefinitely\0" "unrecognized character after (?P\0" "syntax error in subpattern name (missing terminator)\0" "two named subpatterns have the same name\0" "invalid UTF-8 string\0" /* 45 */ "support for \\P, \\p, and \\X has not been compiled\0" "malformed \\P or \\p sequence\0" "unknown property name after \\P or \\p\0" "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0" "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0" /* 50 */ "repeated subpattern is too long\0" /** DEAD **/ "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0" "internal error: overran compiling workspace\0" "internal error: previously-checked referenced subpattern not found\0" "DEFINE group contains more than one branch\0" /* 55 */ "repeating a DEFINE group is not allowed\0" /** DEAD **/ "inconsistent NEWLINE options\0" "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" "a numbered reference must not be zero\0" "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" /* 60 */ "(*VERB) not recognized\0" "number is too big\0" "subpattern name expected\0" "digit expected after (?+\0" "] is an invalid data character in JavaScript compatibility mode\0" /* 65 */ "different names for subpatterns of the same number are not allowed\0" "(*MARK) must have an argument\0" "this version of PCRE is not compiled with Unicode property support\0" "\\c must be followed by an ASCII character\0" "\\k is not followed by a braced, angle-bracketed, or quoted name\0" /* 70 */ "internal error: unknown opcode in find_fixedlength()\0" "\\N is not supported in a class\0" "too many forward references\0" "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0" "invalid UTF-16 string\0" /* 75 */ "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" "character value in \\u.... sequence is too large\0" ; /* Table to identify digits and hex digits. This is used when compiling patterns. Note that the tables in chartables are dependent on the locale, and may mark arbitrary characters as digits - but the PCRE compiling code expects to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have a private table here. It costs 256 bytes, but it is a lot faster than doing character value tests (at least in some simple cases I timed), and in some applications one wants PCRE to compile efficiently as well as match efficiently. For convenience, we use the same bit definitions as in chartables: 0x04 decimal digit 0x08 hexadecimal digit Then we can use ctype_digit and ctype_xdigit in the code. */ /* Using a simple comparison for decimal numbers rather than a memory read is much faster, and the resulting code is simpler (the compiler turns it into a subtraction and unsigned comparison). */ #define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9) #ifndef EBCDIC /* This is the "normal" case, for ASCII systems, and EBCDIC systems running in UTF-8 mode. */ static const pcre_uint8 digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ #else /* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */ static const pcre_uint8 digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */ 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */ 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */ 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */ 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ #endif /* Definition to allow mutual recursion */ static BOOL compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int, int *, int *, branch_chain *, compile_data *, int *); /************************************************* * Find an error text * *************************************************/ /* The error texts are now all in one long string, to save on relocations. As some of the text is of unknown length, we can't use a table of offsets. Instead, just count through the strings. This is not a performance issue because it happens only when there has been a compilation error. Argument: the error number Returns: pointer to the error string */ static const char * find_error_text(int n) { const char *s = error_texts; for (; n > 0; n--) { while (*s++ != 0) {}; if (*s == 0) return "Error text not found (please report)"; } return s; } /************************************************* * Expand the workspace * *************************************************/ /* This function is called during the second compiling phase, if the number of forward references fills the existing workspace, which is originally a block on the stack. A larger block is obtained from malloc() unless the ultimate limit has been reached or the increase will be rather small. Argument: pointer to the compile data block Returns: 0 if all went well, else an error number */ static int expand_workspace(compile_data *cd) { pcre_uchar *newspace; int newsize = cd->workspace_size * 2; if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX; if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX || newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN) return ERR72; newspace = (PUBL(malloc))(IN_UCHARS(newsize)); if (newspace == NULL) return ERR21; memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar)); cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace); if (cd->workspace_size > COMPILE_WORK_SIZE) (PUBL(free))((void *)cd->start_workspace); cd->start_workspace = newspace; cd->workspace_size = newsize; return 0; } /************************************************* * Check for counted repeat * *************************************************/ /* This function is called when a '{' is encountered in a place where it might start a quantifier. It looks ahead to see if it really is a quantifier or not. It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} where the ddds are digits. Arguments: p pointer to the first char after '{' Returns: TRUE or FALSE */ static BOOL is_counted_repeat(const pcre_uchar *p) { if (!IS_DIGIT(*p)) return FALSE; p++; while (IS_DIGIT(*p)) p++; if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; if (*p++ != CHAR_COMMA) return FALSE; if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; if (!IS_DIGIT(*p)) return FALSE; p++; while (IS_DIGIT(*p)) p++; return (*p == CHAR_RIGHT_CURLY_BRACKET); } /************************************************* * Handle escapes * *************************************************/ /* This function is called when a \ has been encountered. It either returns a positive value for a simple escape such as \n, or a negative value which encodes one of the more complicated things such as \d. A backreference to group n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When UTF-8 is enabled, a positive value greater than 255 may be returned. On entry, ptr is pointing at the \. On exit, it is on the final character of the escape sequence. Arguments: ptrptr points to the pattern position pointer errorcodeptr points to the errorcode variable bracount number of previous extracting brackets options the options bits isclass TRUE if inside a character class Returns: zero or positive => a data character negative => a special escape sequence on error, errorcodeptr is set */ static int check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount, int options, BOOL isclass) { /* PCRE_UTF16 has the same value as PCRE_UTF8. */ BOOL utf = (options & PCRE_UTF8) != 0; const pcre_uchar *ptr = *ptrptr + 1; pcre_int32 c; int i; GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ ptr--; /* Set pointer back to the last byte */ /* If backslash is at the end of the pattern, it's an error. */ if (c == 0) *errorcodeptr = ERR1; /* Non-alphanumerics are literals. For digits or letters, do an initial lookup in a table. A non-zero result is something that can be returned immediately. Otherwise further processing may be required. */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ /* Not alphanumeric */ else if (c < CHAR_0 || c > CHAR_z) {} else if ((i = escapes[c - CHAR_0]) != 0) c = i; #else /* EBCDIC coding */ /* Not alphanumeric */ else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {} else if ((i = escapes[c - 0x48]) != 0) c = i; #endif /* Escapes that need further processing, or are illegal. */ else { const pcre_uchar *oldptr; BOOL braced, negated; switch (c) { /* A number of Perl escapes are not handled by PCRE. We give an explicit error. */ case CHAR_l: case CHAR_L: *errorcodeptr = ERR37; break; case CHAR_u: if ((options & PCRE_JAVASCRIPT_COMPAT) != 0) { /* In JavaScript, \u must be followed by four hexadecimal numbers. Otherwise it is a lowercase u letter. */ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0 && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0 && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0 && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0) { c = 0; for (i = 0; i < 4; ++i) { register int cc = *(++ptr); #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); #else /* EBCDIC coding */ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif } #ifdef COMPILE_PCRE8 if (c > (utf ? 0x10ffff : 0xff)) #else #ifdef COMPILE_PCRE16 if (c > (utf ? 0x10ffff : 0xffff)) #endif #endif { *errorcodeptr = ERR76; } else if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; } } else *errorcodeptr = ERR37; break; case CHAR_U: /* In JavaScript, \U is an uppercase U letter. */ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37; break; /* In a character class, \g is just a literal "g". Outside a character class, \g must be followed by one of a number of specific things: (1) A number, either plain or braced. If positive, it is an absolute backreference. If negative, it is a relative backreference. This is a Perl 5.10 feature. (2) Perl 5.10 also supports \g{name} as a reference to a named group. This is part of Perl's movement towards a unified syntax for back references. As this is synonymous with \k{name}, we fudge it up by pretending it really was \k. (3) For Oniguruma compatibility we also support \g followed by a name or a number either in angle brackets or in single quotes. However, these are (possibly recursive) subroutine calls, _not_ backreferences. Just return the -ESC_g code (cf \k). */ case CHAR_g: if (isclass) break; if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE) { c = -ESC_g; break; } /* Handle the Perl-compatible cases */ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { const pcre_uchar *p; for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++) if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break; if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET) { c = -ESC_k; break; } braced = TRUE; ptr++; } else braced = FALSE; if (ptr[1] == CHAR_MINUS) { negated = TRUE; ptr++; } else negated = FALSE; /* The integer range is limited by the machine's int representation. */ c = 0; while (IS_DIGIT(ptr[1])) { if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ { c = -1; break; } c = c * 10 + *(++ptr) - CHAR_0; } if (((unsigned int)c) > INT_MAX) /* Integer overflow */ { while (IS_DIGIT(ptr[1])) ptr++; *errorcodeptr = ERR61; break; } if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET) { *errorcodeptr = ERR57; break; } if (c == 0) { *errorcodeptr = ERR58; break; } if (negated) { if (c > bracount) { *errorcodeptr = ERR15; break; } c = bracount - (c - 1); } c = -(ESC_REF + c); break; /* The handling of escape sequences consisting of a string of digits starting with one that is not zero is not straightforward. By experiment, the way Perl works seems to be as follows: Outside a character class, the digits are read as a decimal number. If the number is less than 10, or if there are that many previous extracting left brackets, then it is a back reference. Otherwise, up to three octal digits are read to form an escaped byte. Thus \123 is likely to be octal 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal value is greater than 377, the least significant 8 bits are taken. Inside a character class, \ followed by a digit is always an octal number. */ case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: if (!isclass) { oldptr = ptr; /* The integer range is limited by the machine's int representation. */ c -= CHAR_0; while (IS_DIGIT(ptr[1])) { if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ { c = -1; break; } c = c * 10 + *(++ptr) - CHAR_0; } if (((unsigned int)c) > INT_MAX) /* Integer overflow */ { while (IS_DIGIT(ptr[1])) ptr++; *errorcodeptr = ERR61; break; } if (c < 10 || c <= bracount) { c = -(ESC_REF + c); break; } ptr = oldptr; /* Put the pointer back and fall through */ } /* Handle an octal number following \. If the first digit is 8 or 9, Perl generates a binary zero byte and treats the digit as a following literal. Thus we have to pull back the pointer by one. */ if ((c = *ptr) >= CHAR_8) { ptr--; c = 0; break; } /* \0 always starts an octal number, but we may drop through to here with a 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 and 16-bit mode, but no more than 3 octal digits. */ case CHAR_0: c -= CHAR_0; while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7) c = c * 8 + *(++ptr) - CHAR_0; #ifdef COMPILE_PCRE8 if (!utf && c > 0xff) *errorcodeptr = ERR51; #endif break; /* \x is complicated. \x{ddd} is a character number which can be greater than 0xff in utf or non-8bit mode, but only if the ddd are hex digits. If not, { is treated as a data character. */ case CHAR_x: if ((options & PCRE_JAVASCRIPT_COMPAT) != 0) { /* In JavaScript, \x must be followed by two hexadecimal numbers. Otherwise it is a lowercase x letter. */ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0 && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0) { c = 0; for (i = 0; i < 2; ++i) { register int cc = *(++ptr); #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); #else /* EBCDIC coding */ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif } } break; } if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { const pcre_uchar *pt = ptr + 2; c = 0; while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) { register int cc = *pt++; if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); #else /* EBCDIC coding */ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif #ifdef COMPILE_PCRE8 if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; } #else #ifdef COMPILE_PCRE16 if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; } #endif #endif } if (c < 0) { while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++; *errorcodeptr = ERR34; } if (*pt == CHAR_RIGHT_CURLY_BRACKET) { if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; ptr = pt; break; } /* If the sequence of hex digits does not end with '}', then we don't recognize this construct; fall through to the normal \x handling. */ } /* Read just a single-byte hex-defined char */ c = 0; while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0) { int cc; /* Some compilers don't like */ cc = *(++ptr); /* ++ in initializers */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); #else /* EBCDIC coding */ if (cc <= CHAR_z) cc += 64; /* Convert to upper case */ c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif } break; /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped. An error is given if the byte following \c is not an ASCII character. This coding is ASCII-specific, but then the whole concept of \cx is ASCII-specific. (However, an EBCDIC equivalent has now been added.) */ case CHAR_c: c = *(++ptr); if (c == 0) { *errorcodeptr = ERR2; break; } #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (c > 127) /* Excludes all non-ASCII in either mode */ { *errorcodeptr = ERR68; break; } if (c >= CHAR_a && c <= CHAR_z) c -= 32; c ^= 0x40; #else /* EBCDIC coding */ if (c >= CHAR_a && c <= CHAR_z) c += 64; c ^= 0xC0; #endif break; /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any other alphanumeric following \ is an error if PCRE_EXTRA was set; otherwise, for Perl compatibility, it is a literal. This code looks a bit odd, but there used to be some cases other than the default, and there may be again in future, so I haven't "optimized" it. */ default: if ((options & PCRE_EXTRA) != 0) switch(c) { default: *errorcodeptr = ERR3; break; } break; } } /* Perl supports \N{name} for character names, as well as plain \N for "not newline". PCRE does not support \N{name}. However, it does support quantification such as \N{2,3}. */ if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET && !is_counted_repeat(ptr+2)) *errorcodeptr = ERR37; /* If PCRE_UCP is set, we change the values for \d etc. */ if ((options & PCRE_UCP) != 0 && c <= -ESC_D && c >= -ESC_w) c -= (ESC_DU - ESC_D); /* Set the pointer to the final character before returning. */ *ptrptr = ptr; return c; } #ifdef SUPPORT_UCP /************************************************* * Handle \P and \p * *************************************************/ /* This function is called after \P or \p has been encountered, provided that PCRE is compiled with support for Unicode properties. On entry, ptrptr is pointing at the P or p. On exit, it is pointing at the final character of the escape sequence. Argument: ptrptr points to the pattern position pointer negptr points to a boolean that is set TRUE for negation else FALSE dptr points to an int that is set to the detailed property value errorcodeptr points to the error code variable Returns: type value from ucp_type_table, or -1 for an invalid type */ static int get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr) { int c, i, bot, top; const pcre_uchar *ptr = *ptrptr; pcre_uchar name[32]; c = *(++ptr); if (c == 0) goto ERROR_RETURN; *negptr = FALSE; /* \P or \p can be followed by a name in {}, optionally preceded by ^ for negation. */ if (c == CHAR_LEFT_CURLY_BRACKET) { if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT) { *negptr = TRUE; ptr++; } for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++) { c = *(++ptr); if (c == 0) goto ERROR_RETURN; if (c == CHAR_RIGHT_CURLY_BRACKET) break; name[i] = c; } if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN; name[i] = 0; } /* Otherwise there is just one following character */ else { name[0] = c; name[1] = 0; } *ptrptr = ptr; /* Search for a recognized property name using binary chop */ bot = 0; top = PRIV(utt_size); while (bot < top) { i = (bot + top) >> 1; c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); if (c == 0) { *dptr = PRIV(utt)[i].value; return PRIV(utt)[i].type; } if (c > 0) bot = i + 1; else top = i; } *errorcodeptr = ERR47; *ptrptr = ptr; return -1; ERROR_RETURN: *errorcodeptr = ERR46; *ptrptr = ptr; return -1; } #endif /************************************************* * Read repeat counts * *************************************************/ /* Read an item of the form {n,m} and return the values. This is called only after is_counted_repeat() has confirmed that a repeat-count quantifier exists, so the syntax is guaranteed to be correct, but we need to check the values. Arguments: p pointer to first char after '{' minp pointer to int for min maxp pointer to int for max returned as -1 if no max errorcodeptr points to error code variable Returns: pointer to '}' on success; current ptr on error, with errorcodeptr set non-zero */ static const pcre_uchar * read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr) { int min = 0; int max = -1; /* Read the minimum value and do a paranoid check: a negative value indicates an integer overflow. */ while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0; if (min < 0 || min > 65535) { *errorcodeptr = ERR5; return p; } /* Read the maximum value if there is one, and again do a paranoid on its size. Also, max must not be less than min. */ if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else { if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) { max = 0; while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0; if (max < 0 || max > 65535) { *errorcodeptr = ERR5; return p; } if (max < min) { *errorcodeptr = ERR4; return p; } } } /* Fill in the required variables, and pass back the pointer to the terminating '}'. */ *minp = min; *maxp = max; return p; } /************************************************* * Subroutine for finding forward reference * *************************************************/ /* This recursive function is called only from find_parens() below. The top-level call starts at the beginning of the pattern. All other calls must start at a parenthesis. It scans along a pattern's text looking for capturing subpatterns, and counting them. If it finds a named pattern that matches the name it is given, it returns its number. Alternatively, if the name is NULL, it returns when it reaches a given numbered subpattern. Recursion is used to keep track of subpatterns that reset the capturing group numbers - the (?| feature. This function was originally called only from the second pass, in which we know that if (?< or (?' or (?P< is encountered, the name will be correctly terminated because that is checked in the first pass. There is now one call to this function in the first pass, to check for a recursive back reference by name (so that we can make the whole group atomic). In this case, we need check only up to the current position in the pattern, and that is still OK because and previous occurrences will have been checked. To make this work, the test for "end of pattern" is a check against cd->end_pattern in the main loop, instead of looking for a binary zero. This means that the special first-pass call can adjust cd->end_pattern temporarily. (Checks for binary zero while processing items within the loop are OK, because afterwards the main loop will terminate.) Arguments: ptrptr address of the current character pointer (updated) cd compile background data name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode utf TRUE if we are in UTF-8 / UTF-16 mode count pointer to the current capturing subpattern number (updated) Returns: the number of the named subpattern, or -1 if not found */ static int find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode, BOOL utf, int *count) { pcre_uchar *ptr = *ptrptr; int start_count = *count; int hwm_count = start_count; BOOL dup_parens = FALSE; /* If the first character is a parenthesis, check on the type of group we are dealing with. The very first call may not start with a parenthesis. */ if (ptr[0] == CHAR_LEFT_PARENTHESIS) { /* Handle specials such as (*SKIP) or (*UTF8) etc. */ if (ptr[1] == CHAR_ASTERISK) ptr += 2; /* Handle a normal, unnamed capturing parenthesis. */ else if (ptr[1] != CHAR_QUESTION_MARK) { *count += 1; if (name == NULL && *count == lorn) return *count; ptr++; } /* All cases now have (? at the start. Remember when we are in a group where the parenthesis numbers are duplicated. */ else if (ptr[2] == CHAR_VERTICAL_LINE) { ptr += 3; dup_parens = TRUE; } /* Handle comments; all characters are allowed until a ket is reached. */ else if (ptr[2] == CHAR_NUMBER_SIGN) { for (ptr += 3; *ptr != 0; ptr++) if (*ptr == CHAR_RIGHT_PARENTHESIS) break; goto FAIL_EXIT; } /* Handle a condition. If it is an assertion, just carry on so that it is processed as normal. If not, skip to the closing parenthesis of the condition (there can't be any nested parens). */ else if (ptr[2] == CHAR_LEFT_PARENTHESIS) { ptr += 2; if (ptr[1] != CHAR_QUESTION_MARK) { while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; if (*ptr != 0) ptr++; } } /* Start with (? but not a condition. */ else { ptr += 2; if (*ptr == CHAR_P) ptr++; /* Allow optional P */ /* We have to disambiguate (? for named groups */ if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK && ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE) { int term; const pcre_uchar *thisname; *count += 1; if (name == NULL && *count == lorn) return *count; term = *ptr++; if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN; thisname = ptr; while (*ptr != term) ptr++; if (name != NULL && lorn == ptr - thisname && STRNCMP_UC_UC(name, thisname, lorn) == 0) return *count; term++; } } } /* Past any initial parenthesis handling, scan for parentheses or vertical bars. Stop if we get to cd->end_pattern. Note that this is important for the first-pass call when this value is temporarily adjusted to stop at the current position. So DO NOT change this to a test for binary zero. */ for (; ptr < cd->end_pattern; ptr++) { /* Skip over backslashed characters and also entire \Q...\E */ if (*ptr == CHAR_BACKSLASH) { if (*(++ptr) == 0) goto FAIL_EXIT; if (*ptr == CHAR_Q) for (;;) { while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {}; if (*ptr == 0) goto FAIL_EXIT; if (*(++ptr) == CHAR_E) break; } continue; } /* Skip over character classes; this logic must be similar to the way they are handled for real. If the first character is '^', skip it. Also, if the first few characters (either before or after ^) are \Q\E or \E we skip them too. This makes for compatibility with Perl. Note the use of STR macros to encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */ if (*ptr == CHAR_LEFT_SQUARE_BRACKET) { BOOL negate_class = FALSE; for (;;) { if (ptr[1] == CHAR_BACKSLASH) { if (ptr[2] == CHAR_E) ptr+= 2; else if (STRNCMP_UC_C8(ptr + 2, STR_Q STR_BACKSLASH STR_E, 3) == 0) ptr += 4; else break; } else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT) { negate_class = TRUE; ptr++; } else break; } /* If the next character is ']', it is a data character that must be skipped, except in JavaScript compatibility mode. */ if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET && (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0) ptr++; while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET) { if (*ptr == 0) return -1; if (*ptr == CHAR_BACKSLASH) { if (*(++ptr) == 0) goto FAIL_EXIT; if (*ptr == CHAR_Q) for (;;) { while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {}; if (*ptr == 0) goto FAIL_EXIT; if (*(++ptr) == CHAR_E) break; } continue; } } continue; } /* Skip comments in /x mode */ if (xmode && *ptr == CHAR_NUMBER_SIGN) { ptr++; while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; #ifdef SUPPORT_UTF if (utf) FORWARDCHAR(ptr); #endif } if (*ptr == 0) goto FAIL_EXIT; continue; } /* Check for the special metacharacters */ if (*ptr == CHAR_LEFT_PARENTHESIS) { int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count); if (rc > 0) return rc; if (*ptr == 0) goto FAIL_EXIT; } else if (*ptr == CHAR_RIGHT_PARENTHESIS) { if (dup_parens && *count < hwm_count) *count = hwm_count; goto FAIL_EXIT; } else if (*ptr == CHAR_VERTICAL_LINE && dup_parens) { if (*count > hwm_count) hwm_count = *count; *count = start_count; } } FAIL_EXIT: *ptrptr = ptr; return -1; } /************************************************* * Find forward referenced subpattern * *************************************************/ /* This function scans along a pattern's text looking for capturing subpatterns, and counting them. If it finds a named pattern that matches the name it is given, it returns its number. Alternatively, if the name is NULL, it returns when it reaches a given numbered subpattern. This is used for forward references to subpatterns. We used to be able to start this scan from the current compiling point, using the current count value from cd->bracount, and do it all in a single loop, but the addition of the possibility of duplicate subpattern numbers means that we have to scan from the very start, in order to take account of such duplicates, and to use a recursive function to keep track of the different types of group. Arguments: cd compile background data name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode utf TRUE if we are in UTF-8 / UTF-16 mode Returns: the number of the found subpattern, or -1 if not found */ static int find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode, BOOL utf) { pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern; int count = 0; int rc; /* If the pattern does not start with an opening parenthesis, the first call to find_parens_sub() will scan right to the end (if necessary). However, if it does start with a parenthesis, find_parens_sub() will return when it hits the matching closing parens. That is why we have to have a loop. */ for (;;) { rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count); if (rc > 0 || *ptr++ == 0) break; } return rc; } /************************************************* * Find first significant op code * *************************************************/ /* This is called by several functions that scan a compiled expression looking for a fixed first character, or an anchoring op code etc. It skips over things that do not influence this. For some calls, it makes sense to skip negative forward and all backward assertions, and also the \b assertion; for others it does not. Arguments: code pointer to the start of the group skipassert TRUE if certain assertions are to be skipped Returns: pointer to the first significant opcode */ static const pcre_uchar* first_significant_code(const pcre_uchar *code, BOOL skipassert) { for (;;) { switch ((int)*code) { case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: if (!skipassert) return code; do code += GET(code, 1); while (*code == OP_ALT); code += PRIV(OP_lengths)[*code]; break; case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: if (!skipassert) return code; /* Fall through */ case OP_CALLOUT: case OP_CREF: case OP_NCREF: case OP_RREF: case OP_NRREF: case OP_DEF: code += PRIV(OP_lengths)[*code]; break; default: return code; } } /* Control never reaches here */ } /************************************************* * Find the fixed length of a branch * *************************************************/ /* Scan a branch and compute the fixed length of subject that will match it, if the length is fixed. This is needed for dealing with backward assertions. In UTF8 mode, the result is in characters rather than bytes. The branch is temporarily terminated with OP_END when this function is called. This function is called when a backward assertion is encountered, so that if it fails, the error message can point to the correct place in the pattern. However, we cannot do this when the assertion contains subroutine calls, because they can be forward references. We solve this by remembering this case and doing the check at the end; a flag specifies which mode we are running in. Arguments: code points to the start of the pattern (the bracket) utf TRUE in UTF-8 / UTF-16 mode atend TRUE if called when the pattern is complete cd the "compile data" structure Returns: the fixed length, or -1 if there is no fixed length, or -2 if \C was encountered (in UTF-8 mode only) or -3 if an OP_RECURSE item was encountered and atend is FALSE or -4 if an unknown opcode was encountered (internal error) */ static int find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd) { int length = -1; register int branchlength = 0; register pcre_uchar *cc = code + 1 + LINK_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ for (;;) { int d; pcre_uchar *ce, *cs; register int op = *cc; switch (op) { /* We only need to continue for OP_CBRA (normal capturing bracket) and OP_BRA (normal non-capturing bracket) because the other variants of these opcodes are all concerned with unlimited repeated groups, which of course are not of fixed length. */ case OP_CBRA: case OP_BRA: case OP_ONCE: case OP_ONCE_NC: case OP_COND: d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; /* Reached end of a branch; if it's a ket it is the end of a nested call. If it's ALT it is an alternation in a nested call. An ACCEPT is effectively an ALT. If it is END it's the end of the outer call. All can be handled by the same code. Note that we must not include the OP_KETRxxx opcodes here, because they all imply an unlimited repeat. */ case OP_ALT: case OP_KET: case OP_END: case OP_ACCEPT: case OP_ASSERT_ACCEPT: if (length < 0) length = branchlength; else if (length != branchlength) return -1; if (*cc != OP_ALT) return length; cc += 1 + LINK_SIZE; branchlength = 0; break; /* A true recursion implies not fixed length, but a subroutine call may be OK. If the subroutine is a forward reference, we can't deal with it until the end of the pattern, so return -3. */ case OP_RECURSE: if (!atend) return -3; cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */ do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */ if (cc > cs && cc < ce) return -1; /* Recursion */ d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd); if (d < 0) return d; branchlength += d; cc += 1 + LINK_SIZE; break; /* Skip over assertive subpatterns */ case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do cc += GET(cc, 1); while (*cc == OP_ALT); cc += PRIV(OP_lengths)[*cc]; break; /* Skip over things that don't match chars */ case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: cc += cc[1] + PRIV(OP_lengths)[*cc]; break; case OP_CALLOUT: case OP_CIRC: case OP_CIRCM: case OP_CLOSE: case OP_COMMIT: case OP_CREF: case OP_DEF: case OP_DOLL: case OP_DOLLM: case OP_EOD: case OP_EODN: case OP_FAIL: case OP_NCREF: case OP_NRREF: case OP_NOT_WORD_BOUNDARY: case OP_PRUNE: case OP_REVERSE: case OP_RREF: case OP_SET_SOM: case OP_SKIP: case OP_SOD: case OP_SOM: case OP_THEN: case OP_WORD_BOUNDARY: cc += PRIV(OP_lengths)[*cc]; break; /* Handle literal characters */ case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: branchlength++; cc += 2; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; /* Handle exact repetitions. The count is already in characters, but we need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: case OP_EXACTI: case OP_NOTEXACT: case OP_NOTEXACTI: branchlength += GET2(cc,1); cc += 2 + IMM2_SIZE; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; cc += 1 + IMM2_SIZE + 1; break; /* Handle single-char matchers */ case OP_PROP: case OP_NOTPROP: cc += 2; /* Fall through */ case OP_HSPACE: case OP_VSPACE: case OP_NOT_HSPACE: case OP_NOT_VSPACE: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: case OP_ALLANY: branchlength++; cc++; break; /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode; otherwise \C is coded as OP_ALLANY. */ case OP_ANYBYTE: return -2; /* Check a class for variable quantification */ #if defined SUPPORT_UTF || defined COMPILE_PCRE16 case OP_XCLASS: cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: cc += PRIV(OP_lengths)[OP_CLASS]; switch (*cc) { case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: return -1; case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1; branchlength += GET2(cc,1); cc += 1 + 2 * IMM2_SIZE; break; default: branchlength++; } break; /* Anything else is variable length */ case OP_ANYNL: case OP_BRAMINZERO: case OP_BRAPOS: case OP_BRAPOSZERO: case OP_BRAZERO: case OP_CBRAPOS: case OP_EXTUNI: case OP_KETRMAX: case OP_KETRMIN: case OP_KETRPOS: case OP_MINPLUS: case OP_MINPLUSI: case OP_MINQUERY: case OP_MINQUERYI: case OP_MINSTAR: case OP_MINSTARI: case OP_MINUPTO: case OP_MINUPTOI: case OP_NOTMINPLUS: case OP_NOTMINPLUSI: case OP_NOTMINQUERY: case OP_NOTMINQUERYI: case OP_NOTMINSTAR: case OP_NOTMINSTARI: case OP_NOTMINUPTO: case OP_NOTMINUPTOI: case OP_NOTPLUS: case OP_NOTPLUSI: case OP_NOTPOSPLUS: case OP_NOTPOSPLUSI: case OP_NOTPOSQUERY: case OP_NOTPOSQUERYI: case OP_NOTPOSSTAR: case OP_NOTPOSSTARI: case OP_NOTPOSUPTO: case OP_NOTPOSUPTOI: case OP_NOTQUERY: case OP_NOTQUERYI: case OP_NOTSTAR: case OP_NOTSTARI: case OP_NOTUPTO: case OP_NOTUPTOI: case OP_PLUS: case OP_PLUSI: case OP_POSPLUS: case OP_POSPLUSI: case OP_POSQUERY: case OP_POSQUERYI: case OP_POSSTAR: case OP_POSSTARI: case OP_POSUPTO: case OP_POSUPTOI: case OP_QUERY: case OP_QUERYI: case OP_REF: case OP_REFI: case OP_SBRA: case OP_SBRAPOS: case OP_SCBRA: case OP_SCBRAPOS: case OP_SCOND: case OP_SKIPZERO: case OP_STAR: case OP_STARI: case OP_TYPEMINPLUS: case OP_TYPEMINQUERY: case OP_TYPEMINSTAR: case OP_TYPEMINUPTO: case OP_TYPEPLUS: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSSTAR: case OP_TYPEPOSUPTO: case OP_TYPEQUERY: case OP_TYPESTAR: case OP_TYPEUPTO: case OP_UPTO: case OP_UPTOI: return -1; /* Catch unrecognized opcodes so that when new ones are added they are not forgotten, as has happened in the past. */ default: return -4; } } /* Control never gets here */ } /************************************************* * Scan compiled regex for specific bracket * *************************************************/ /* This little function scans through a compiled pattern until it finds a capturing bracket with the given number, or, if the number is negative, an instance of OP_REVERSE for a lookbehind. The function is global in the C sense so that it can be called from pcre_study() when finding the minimum matching length. Arguments: code points to start of expression utf TRUE in UTF-8 / UTF-16 mode number the required bracket number or negative to find a lookbehind Returns: pointer to the opcode for the bracket, or NULL if not found */ const pcre_uchar * PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number) { 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 recursion */ else if (c == OP_REVERSE) { if (number < 0) return (pcre_uchar *)code; code += PRIV(OP_lengths)[c]; } /* Handle capturing bracket */ else if (c == OP_CBRA || c == OP_SCBRA || c == OP_CBRAPOS || c == OP_SCBRAPOS) { int n = GET2(code, 1+LINK_SIZE); if (n == number) return (pcre_uchar *)code; code += PRIV(OP_lengths)[c]; } /* Otherwise, we can get the item's length from the table, except that for repeated character types, we have to test for \p and \P, which have an extra two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we must add in its length. */ else { switch(c) { case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; break; case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSUPTO: if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: code += code[1]; break; case OP_THEN_ARG: code += code[1]; break; } /* Add in the fixed length from the table */ code += PRIV(OP_lengths)[c]; /* 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 arrange to skip the extra bytes. */ #ifdef SUPPORT_UTF if (utf) switch(c) { case OP_CHAR: case OP_CHARI: case OP_EXACT: case OP_EXACTI: case OP_UPTO: case OP_UPTOI: case OP_MINUPTO: case OP_MINUPTOI: case OP_POSUPTO: case OP_POSUPTOI: case OP_STAR: case OP_STARI: case OP_MINSTAR: case OP_MINSTARI: case OP_POSSTAR: case OP_POSSTARI: case OP_PLUS: case OP_PLUSI: case OP_MINPLUS: case OP_MINPLUSI: case OP_POSPLUS: case OP_POSPLUSI: case OP_QUERY: case OP_QUERYI: case OP_MINQUERY: case OP_MINQUERYI: case OP_POSQUERY: case OP_POSQUERYI: if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); break; } #else (void)(utf); /* Keep compiler happy by referencing function argument */ #endif } } } /************************************************* * Scan compiled regex for recursion reference * *************************************************/ /* This little function scans through a compiled pattern until it finds an instance of OP_RECURSE. Arguments: code points to start of expression utf TRUE in UTF-8 / UTF-16 mode Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ static const pcre_uchar * find_recurse(const pcre_uchar *code, BOOL utf) { for (;;) { register int c = *code; if (c == OP_END) return NULL; 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); /* Otherwise, we can get the item's length from the table, except that for repeated character types, we have to test for \p and \P, which have an extra two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we must add in its length. */ else { switch(c) { case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; break; case OP_TYPEPOSUPTO: case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: code += code[1]; break; case OP_THEN_ARG: code += code[1]; break; } /* Add in the fixed length from the table */ code += PRIV(OP_lengths)[c]; /* 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 arrange to skip the extra bytes. */ #ifdef SUPPORT_UTF if (utf) switch(c) { case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: case OP_EXACT: case OP_EXACTI: case OP_NOTEXACT: case OP_NOTEXACTI: case OP_UPTO: case OP_UPTOI: case OP_NOTUPTO: case OP_NOTUPTOI: case OP_MINUPTO: case OP_MINUPTOI: case OP_NOTMINUPTO: case OP_NOTMINUPTOI: case OP_POSUPTO: case OP_POSUPTOI: case OP_NOTPOSUPTO: case OP_NOTPOSUPTOI: case OP_STAR: case OP_STARI: case OP_NOTSTAR: case OP_NOTSTARI: case OP_MINSTAR: case OP_MINSTARI: case OP_NOTMINSTAR: case OP_NOTMINSTARI: case OP_POSSTAR: case OP_POSSTARI: case OP_NOTPOSSTAR: case OP_NOTPOSSTARI: case OP_PLUS: case OP_PLUSI: case OP_NOTPLUS: case OP_NOTPLUSI: case OP_MINPLUS: case OP_MINPLUSI: case OP_NOTMINPLUS: case OP_NOTMINPLUSI: case OP_POSPLUS: case OP_POSPLUSI: case OP_NOTPOSPLUS: case OP_NOTPOSPLUSI: case OP_QUERY: case OP_QUERYI: case OP_NOTQUERY: case OP_NOTQUERYI: case OP_MINQUERY: case OP_MINQUERYI: case OP_NOTMINQUERY: case OP_NOTMINQUERYI: case OP_POSQUERY: case OP_POSQUERYI: case OP_NOTPOSQUERY: case OP_NOTPOSQUERYI: if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); break; } #else (void)(utf); /* Keep compiler happy by referencing function argument */ #endif } } } /************************************************* * Scan compiled branch for non-emptiness * *************************************************/ /* This function scans through a branch of a compiled pattern to see whether it can match the empty string or not. It is called from could_be_empty() below and from compile_branch() when checking for an unlimited repeat of a group that can match nothing. Note that first_significant_code() skips over backward and negative forward assertions when its final argument is TRUE. If we hit an unclosed bracket, we return "empty" - this means we've struck an inner bracket whose current branch will already have been scanned. Arguments: code points to start of search endcode points to where to stop utf TRUE if in UTF-8 / UTF-16 mode cd contains pointers to tables etc. Returns: TRUE if what is matched could be empty */ static BOOL could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode, BOOL utf, compile_data *cd) { register int c; for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); code < endcode; code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) { const pcre_uchar *ccode; c = *code; /* Skip over forward assertions; the other assertions are skipped by first_significant_code() with a TRUE final argument. */ if (c == OP_ASSERT) { do code += GET(code, 1); while (*code == OP_ALT); c = *code; continue; } /* For a recursion/subroutine call, if its end has been reached, which implies a backward reference subroutine call, we can scan it. If it's a forward reference subroutine call, we can't. To detect forward reference we have to scan up the list that is kept in the workspace. This function is called only when doing the real compile, not during the pre-compile that measures the size of the compiled pattern. */ if (c == OP_RECURSE) { const pcre_uchar *scode; BOOL empty_branch; /* Test for forward reference */ for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE) if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE; /* Not a forward reference, test for completed backward reference */ empty_branch = FALSE; scode = cd->start_code + GET(code, 1); if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ /* Completed backwards reference */ do { if (could_be_empty_branch(scode, endcode, utf, cd)) { empty_branch = TRUE; break; } scode += GET(scode, 1); } while (*scode == OP_ALT); if (!empty_branch) return FALSE; /* All branches are non-empty */ continue; } /* Groups with zero repeats can of course be empty; skip them. */ if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO || c == OP_BRAPOSZERO) { code += PRIV(OP_lengths)[c]; do code += GET(code, 1); while (*code == OP_ALT); c = *code; continue; } /* A nested group that is already marked as "could be empty" can just be skipped. */ if (c == OP_SBRA || c == OP_SBRAPOS || c == OP_SCBRA || c == OP_SCBRAPOS) { do code += GET(code, 1); while (*code == OP_ALT); c = *code; continue; } /* For other groups, scan the branches. */ if (c == OP_BRA || c == OP_BRAPOS || c == OP_CBRA || c == OP_CBRAPOS || c == OP_ONCE || c == OP_ONCE_NC || c == OP_COND) { BOOL empty_branch; if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */ /* If a conditional group has only one branch, there is a second, implied, empty branch, so just skip over the conditional, because it could be empty. Otherwise, scan the individual branches of the group. */ if (c == OP_COND && code[GET(code, 1)] != OP_ALT) code += GET(code, 1); else { empty_branch = FALSE; do { if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd)) empty_branch = TRUE; code += GET(code, 1); } while (*code == OP_ALT); if (!empty_branch) return FALSE; /* All branches are non-empty */ } c = *code; continue; } /* Handle the other opcodes */ switch (c) { /* Check for quantifiers after a class. XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single high-valued characters. The length in PRIV(OP_lengths)[] is zero; the actual length is stored in the compiled code, so we must update "code" here. */ #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: ccode = code += GET(code, 1); goto CHECK_CLASS_REPEAT; #endif case OP_CLASS: case OP_NCLASS: ccode = code + PRIV(OP_lengths)[OP_CLASS]; #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 CHECK_CLASS_REPEAT: #endif switch (*ccode) { case OP_CRSTAR: /* These could be empty; continue */ case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: break; default: /* Non-repeat => class must match */ case OP_CRPLUS: /* These repeats aren't empty */ case OP_CRMINPLUS: return FALSE; case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */ break; } break; /* Opcodes that must match a character */ case OP_PROP: case OP_NOTPROP: case OP_EXTUNI: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: case OP_ALLANY: case OP_ANYBYTE: case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_EXACT: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTPOSPLUS: case OP_NOTEXACT: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: case OP_TYPEEXACT: return FALSE; /* These are going to continue, as they may be empty, but we have to fudge the length for the \p and \P cases. */ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; break; /* Same for these */ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; /* End of branch */ case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_KETRPOS: case OP_ALT: return TRUE; /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO, MINUPTO, and POSUPTO may be followed by a multibyte character */ #ifdef SUPPORT_UTF case OP_STAR: case OP_STARI: case OP_MINSTAR: case OP_MINSTARI: case OP_POSSTAR: case OP_POSSTARI: case OP_QUERY: case OP_QUERYI: case OP_MINQUERY: case OP_MINQUERYI: case OP_POSQUERY: case OP_POSQUERYI: if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]); break; case OP_UPTO: case OP_UPTOI: case OP_MINUPTO: case OP_MINUPTOI: case OP_POSUPTO: case OP_POSUPTOI: if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]); break; #endif /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument string. */ case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: code += code[1]; break; case OP_THEN_ARG: code += code[1]; break; /* None of the remaining opcodes are required to match a character. */ default: break; } } return TRUE; } /************************************************* * Scan compiled regex for non-emptiness * *************************************************/ /* This function is called to check for left recursive calls. We want to check the current branch of the current pattern to see if it could match the empty string. If it could, we must look outwards for branches at other levels, stopping when we pass beyond the bracket which is the subject of the recursion. This function is called only during the real compile, not during the pre-compile. Arguments: code points to start of the recursion endcode points to where to stop (current RECURSE item) bcptr points to the chain of current (unclosed) branch starts utf TRUE if in UTF-8 / UTF-16 mode cd pointers to tables etc Returns: TRUE if what is matched could be empty */ static BOOL could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode, branch_chain *bcptr, BOOL utf, compile_data *cd) { while (bcptr != NULL && bcptr->current_branch >= code) { if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd)) return FALSE; bcptr = bcptr->outer; } return TRUE; } /************************************************* * Check for POSIX class syntax * *************************************************/ /* This function is called when the sequence "[:" or "[." or "[=" is encountered in a character class. It checks whether this is followed by a sequence of characters terminated by a matching ":]" or ".]" or "=]". If we reach an unescaped ']' without the special preceding character, return FALSE. Originally, this function only recognized a sequence of letters between the terminators, but it seems that Perl recognizes any sequence of characters, though of course unknown POSIX names are subsequently rejected. Perl gives an "Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE didn't consider this to be a POSIX class. Likewise for [:1234:]. The problem in trying to be exactly like Perl is in the handling of escapes. We have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code below handles the special case of \], but does not try to do any other escape processing. This makes it different from Perl for cases such as [:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize "l\ower". This is a lesser evil that not diagnosing bad classes when Perl does, I think. A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not. It seems that the appearance of a nested POSIX class supersedes an apparent external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or a digit. In Perl, unescaped square brackets may also appear as part of class names. For example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for [:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not seem right at all. PCRE does not allow closing square brackets in POSIX class names. Arguments: ptr pointer to the initial [ endptr where to return the end pointer Returns: TRUE or FALSE */ static BOOL check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr) { int terminator; /* Don't combine these lines; the Solaris cc */ terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ for (++ptr; *ptr != 0; ptr++) { if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) ptr++; else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; else { if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { *endptr = ptr; return TRUE; } if (*ptr == CHAR_LEFT_SQUARE_BRACKET && (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, endptr)) return FALSE; } } return FALSE; } /************************************************* * Check POSIX class name * *************************************************/ /* This function is called to check the name given in a POSIX-style class entry such as [:alnum:]. Arguments: ptr points to the first letter len the length of the name Returns: a value representing the name, or -1 if unknown */ static int check_posix_name(const pcre_uchar *ptr, int len) { const char *pn = posix_names; register int yield = 0; while (posix_name_lengths[yield] != 0) { if (len == posix_name_lengths[yield] && STRNCMP_UC_C8(ptr, pn, len) == 0) return yield; pn += posix_name_lengths[yield] + 1; yield++; } return -1; } /************************************************* * Adjust OP_RECURSE items in repeated group * *************************************************/ /* OP_RECURSE items contain an offset from the start of the regex to the group that is referenced. This means that groups can be replicated for fixed repetition simply by copying (because the recursion is allowed to refer to earlier groups that are outside the current group). However, when a group is optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is inserted before it, after it has been compiled. This means that any OP_RECURSE items within it that refer to the group itself or any contained groups have to have their offsets adjusted. That one of the jobs of this function. Before it is called, the partially compiled regex must be temporarily terminated with OP_END. This function has been extended with the possibility of forward references for recursions and subroutine calls. It must also check the list of such references for the group we are dealing with. If it finds that one of the recursions in the current group is on this list, it adjusts the offset in the list, not the value in the reference (which is a group number). Arguments: group points to the start of the group adjust the amount by which the group is to be moved utf TRUE in UTF-8 / UTF-16 mode cd contains pointers to tables etc. save_hwm the hwm forward reference pointer at the start of the group Returns: nothing */ static void adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd, pcre_uchar *save_hwm) { pcre_uchar *ptr = group; while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL) { int offset; pcre_uchar *hc; /* See if this recursion is on the forward reference list. If so, adjust the reference. */ for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE) { offset = GET(hc, 0); if (cd->start_code + offset == ptr + 1) { PUT(hc, 0, offset + adjust); break; } } /* Otherwise, adjust the recursion offset if it's after the start of this group. */ if (hc >= cd->hwm) { offset = GET(ptr, 1); if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust); } ptr += 1 + LINK_SIZE; } } /************************************************* * Insert an automatic callout point * *************************************************/ /* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert callout points before each pattern item. Arguments: code current code pointer ptr current pattern pointer cd pointers to tables etc Returns: new code pointer */ static pcre_uchar * auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd) { *code++ = OP_CALLOUT; *code++ = 255; PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ return code + 2 * LINK_SIZE; } /************************************************* * Complete a callout item * *************************************************/ /* A callout item contains the length of the next item in the pattern, which we can't fill in till after we have reached the relevant point. This is used for both automatic and manual callouts. Arguments: previous_callout points to previous callout item ptr current pattern pointer cd pointers to tables etc Returns: nothing */ static void complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd) { int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2)); PUT(previous_callout, 2 + LINK_SIZE, length); } #ifdef SUPPORT_UCP /************************************************* * Get othercase range * *************************************************/ /* This function is passed the start and end of a class range, in UTF-8 mode with UCP support. It searches up the characters, looking for internal ranges of characters in the "other" case. Each call returns the next one, updating the start address. Arguments: cptr points to starting character value; updated d end value ocptr where to put start of othercase range odptr where to put end of othercase range Yield: TRUE when range returned; FALSE when no more */ static BOOL get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr, unsigned int *odptr) { unsigned int c, othercase, next; for (c = *cptr; c <= d; c++) { if ((othercase = UCD_OTHERCASE(c)) != c) break; } if (c > d) return FALSE; *ocptr = othercase; next = othercase + 1; for (++c; c <= d; c++) { if (UCD_OTHERCASE(c) != next) break; next++; } *odptr = next - 1; *cptr = c; return TRUE; } /************************************************* * Check a character and a property * *************************************************/ /* This function is called by check_auto_possessive() when a property item is adjacent to a fixed character. Arguments: c the character ptype the property type pdata the data for the type negated TRUE if it's a negated property (\P or \p{^) Returns: TRUE if auto-possessifying is OK */ static BOOL check_char_prop(int c, int ptype, int pdata, BOOL negated) { const ucd_record *prop = GET_UCD(c); switch(ptype) { case PT_LAMP: return (prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt) == negated; case PT_GC: return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; case PT_PC: return (pdata == prop->chartype) == negated; case PT_SC: return (pdata == prop->script) == negated; /* These are specials */ case PT_ALNUM: return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; case PT_SPACE: /* Perl space */ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == negated; case PT_PXSPACE: /* POSIX space */ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == negated; case PT_WORD: return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == negated; } return FALSE; } #endif /* SUPPORT_UCP */ /************************************************* * Check if auto-possessifying is possible * *************************************************/ /* This function is called for unlimited repeats of certain items, to see whether the next thing could possibly match the repeated item. If not, it makes sense to automatically possessify the repeated item. Arguments: previous pointer to the repeated opcode utf TRUE in UTF-8 / UTF-16 mode ptr next character in pattern options options bits cd contains pointers to tables etc. Returns: TRUE if possessifying is wanted */ static BOOL check_auto_possessive(const pcre_uchar *previous, BOOL utf, const pcre_uchar *ptr, int options, compile_data *cd) { pcre_int32 c, next; int op_code = *previous++; /* Skip whitespace and comments in extended mode */ if ((options & PCRE_EXTENDED) != 0) { for (;;) { while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == CHAR_NUMBER_SIGN) { ptr++; while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; #ifdef SUPPORT_UTF if (utf) FORWARDCHAR(ptr); #endif } } else break; } } /* If the next item is one that we can handle, get its value. A non-negative value is a character, a negative value is an escape value. */ if (*ptr == CHAR_BACKSLASH) { int temperrorcode = 0; next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE); if (temperrorcode != 0) return FALSE; ptr++; /* Point after the escape sequence */ } else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0) { #ifdef SUPPORT_UTF if (utf) { GETCHARINC(next, ptr); } else #endif next = *ptr++; } else return FALSE; /* Skip whitespace and comments in extended mode */ if ((options & PCRE_EXTENDED) != 0) { for (;;) { while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == CHAR_NUMBER_SIGN) { ptr++; while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; #ifdef SUPPORT_UTF if (utf) FORWARDCHAR(ptr); #endif } } else break; } } /* If the next thing is itself optional, we have to give up. */ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) return FALSE; /* Now compare the next item with the previous opcode. First, handle cases when the next item is a character. */ if (next >= 0) switch(op_code) { case OP_CHAR: #ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif return c != next; /* For CHARI (caseless character) we must check the other case. If we have Unicode property support, we can use it to test the other case of high-valued characters. */ case OP_CHARI: #ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif if (c == next) return FALSE; #ifdef SUPPORT_UTF if (utf) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else #ifdef SUPPORT_UCP othercase = UCD_OTHERCASE((unsigned int)next); #else othercase = NOTACHAR; #endif return (unsigned int)c != othercase; } else #endif /* SUPPORT_UTF */ return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ case OP_NOT: #ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif return c == next; case OP_NOTI: #ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif if (c == next) return TRUE; #ifdef SUPPORT_UTF if (utf) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else #ifdef SUPPORT_UCP othercase = UCD_OTHERCASE((unsigned int)next); #else othercase = NOTACHAR; #endif return (unsigned int)c == othercase; } else #endif /* SUPPORT_UTF */ return (c == TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ case OP_DIGIT: return next > 255 || (cd->ctypes[next] & ctype_digit) == 0; case OP_NOT_DIGIT: return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0; case OP_WHITESPACE: return next > 255 || (cd->ctypes[next] & ctype_space) == 0; case OP_NOT_WHITESPACE: return next <= 255 && (cd->ctypes[next] & ctype_space) != 0; case OP_WORDCHAR: return next > 255 || (cd->ctypes[next] & ctype_word) == 0; case OP_NOT_WORDCHAR: return next <= 255 && (cd->ctypes[next] & ctype_word) != 0; case OP_HSPACE: case OP_NOT_HSPACE: switch(next) { case 0x09: case 0x20: case 0xa0: case 0x1680: case 0x180e: case 0x2000: case 0x2001: case 0x2002: case 0x2003: case 0x2004: case 0x2005: case 0x2006: case 0x2007: case 0x2008: case 0x2009: case 0x200A: case 0x202f: case 0x205f: case 0x3000: return op_code == OP_NOT_HSPACE; default: return op_code != OP_NOT_HSPACE; } case OP_ANYNL: case OP_VSPACE: case OP_NOT_VSPACE: switch(next) { case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x85: case 0x2028: case 0x2029: return op_code == OP_NOT_VSPACE; default: return op_code != OP_NOT_VSPACE; } #ifdef SUPPORT_UCP case OP_PROP: return check_char_prop(next, previous[0], previous[1], FALSE); case OP_NOTPROP: return check_char_prop(next, previous[0], previous[1], TRUE); #endif default: return FALSE; } /* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are generated only when PCRE_UCP is *not* set, that is, when only ASCII characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are replaced by OP_PROP codes when PCRE_UCP is set. */ switch(op_code) { case OP_CHAR: case OP_CHARI: #ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif switch(-next) { case ESC_d: return c > 255 || (cd->ctypes[c] & ctype_digit) == 0; case ESC_D: return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0; case ESC_s: return c > 255 || (cd->ctypes[c] & ctype_space) == 0; case ESC_S: return c <= 255 && (cd->ctypes[c] & ctype_space) != 0; case ESC_w: return c > 255 || (cd->ctypes[c] & ctype_word) == 0; case ESC_W: return c <= 255 && (cd->ctypes[c] & ctype_word) != 0; case ESC_h: case ESC_H: switch(c) { case 0x09: case 0x20: case 0xa0: case 0x1680: case 0x180e: case 0x2000: case 0x2001: case 0x2002: case 0x2003: case 0x2004: case 0x2005: case 0x2006: case 0x2007: case 0x2008: case 0x2009: case 0x200A: case 0x202f: case 0x205f: case 0x3000: return -next != ESC_h; default: return -next == ESC_h; } case ESC_v: case ESC_V: switch(c) { case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x85: case 0x2028: case 0x2029: return -next != ESC_v; default: return -next == ESC_v; } /* When PCRE_UCP is set, these values get generated for \d etc. Find their substitutions and process them. The result will always be either -ESC_p or -ESC_P. Then fall through to process those values. */ #ifdef SUPPORT_UCP case ESC_du: case ESC_DU: case ESC_wu: case ESC_WU: case ESC_su: case ESC_SU: { int temperrorcode = 0; ptr = substitutes[-next - ESC_DU]; next = check_escape(&ptr, &temperrorcode, 0, options, FALSE); if (temperrorcode != 0) return FALSE; ptr++; /* For compatibility */ } /* Fall through */ case ESC_p: case ESC_P: { int ptype, pdata, errorcodeptr; BOOL negated; ptr--; /* Make ptr point at the p or P */ ptype = get_ucp(&ptr, &negated, &pdata, &errorcodeptr); if (ptype < 0) return FALSE; ptr++; /* Point past the final curly ket */ /* If the property item is optional, we have to give up. (When generated from \d etc by PCRE_UCP, this test will have been applied much earlier, to the original \d etc. At this point, ptr will point to a zero byte. */ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) return FALSE; /* Do the property check. */ return check_char_prop(c, ptype, pdata, (next == -ESC_P) != negated); } #endif default: return FALSE; } /* In principle, support for Unicode properties should be integrated here as well. It means re-organizing the above code so as to get hold of the property values before switching on the op-code. However, I wonder how many patterns combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set, these op-codes are never generated.) */ case OP_DIGIT: return next == -ESC_D || next == -ESC_s || next == -ESC_W || next == -ESC_h || next == -ESC_v || next == -ESC_R; case OP_NOT_DIGIT: return next == -ESC_d; case OP_WHITESPACE: return next == -ESC_S || next == -ESC_d || next == -ESC_w; case OP_NOT_WHITESPACE: return next == -ESC_s || next == -ESC_h || next == -ESC_v || next == -ESC_R; case OP_HSPACE: return next == -ESC_S || next == -ESC_H || next == -ESC_d || next == -ESC_w || next == -ESC_v || next == -ESC_R; case OP_NOT_HSPACE: return next == -ESC_h; /* Can't have \S in here because VT matches \S (Perl anomaly) */ case OP_ANYNL: case OP_VSPACE: return next == -ESC_V || next == -ESC_d || next == -ESC_w; case OP_NOT_VSPACE: return next == -ESC_v || next == -ESC_R; case OP_WORDCHAR: return next == -ESC_W || next == -ESC_s || next == -ESC_h || next == -ESC_v || next == -ESC_R; case OP_NOT_WORDCHAR: return next == -ESC_w || next == -ESC_d; default: return FALSE; } /* Control does not reach here */ } /************************************************* * Compile one branch * *************************************************/ /* Scan the pattern, compiling it into the a vector. If the options are changed during the branch, the pointer is used to change the external options bits. This function is used during the pre-compile phase when we are trying to find out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: optionsptr pointer to the option bits codeptr points to the pointer to the current code point ptrptr points to the current pattern pointer errorcodeptr points to error code variable firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) reqcharptr set to the last literal character required, else < 0 bcptr points to current branch chain cond_depth conditional nesting depth cd contains pointers to tables etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase Returns: TRUE on success FALSE, with *errorcodeptr set non-zero on error */ static BOOL compile_branch(int *optionsptr, pcre_uchar **codeptr, const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth, compile_data *cd, int *lengthptr) { int repeat_type, op_type; int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ int bravalue = 0; int greedy_default, greedy_non_default; pcre_int32 firstchar, reqchar; pcre_int32 zeroreqchar, zerofirstchar; pcre_int32 req_caseopt, reqvary, tempreqvary; int options = *optionsptr; /* May change dynamically */ int after_manual_callout = 0; int length_prevgroup = 0; register int c; register pcre_uchar *code = *codeptr; pcre_uchar *last_code = code; pcre_uchar *orig_code = code; pcre_uchar *tempcode; BOOL inescq = FALSE; BOOL groupsetfirstchar = FALSE; const pcre_uchar *ptr = *ptrptr; const pcre_uchar *tempptr; const pcre_uchar *nestptr = NULL; pcre_uchar *previous = NULL; pcre_uchar *previous_callout = NULL; pcre_uchar *save_hwm = NULL; pcre_uint8 classbits[32]; /* We can fish out the UTF-8 setting once and for all into a BOOL, but we must not do this for other options (e.g. PCRE_EXTENDED) because they may change dynamically as we process the pattern. */ #ifdef SUPPORT_UTF /* PCRE_UTF16 has the same value as PCRE_UTF8. */ BOOL utf = (options & PCRE_UTF8) != 0; pcre_uchar utf_chars[6]; #else BOOL utf = FALSE; #endif /* Helper variables for OP_XCLASS opcode (for characters > 255). */ #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 BOOL xclass; pcre_uchar *class_uchardata; pcre_uchar *class_uchardata_base; #endif #ifdef PCRE_DEBUG if (lengthptr != NULL) DPRINTF((">> start branch\n")); #endif /* Set up the default and non-default settings for greediness */ greedy_default = ((options & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; /* Initialize no first byte, no required byte. REQ_UNSET means "no char matching encountered yet". It gets changed to REQ_NONE if we hit something that matches a non-fixed char first char; reqchar just remains unset if we never find one. When we hit a repeat whose minimum is zero, we may have to adjust these values to take the zero repeat into account. This is implemented by setting them to zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual item types that can be repeated set these backoff variables appropriately. */ firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET; /* The variable req_caseopt contains either the REQ_CASELESS value or zero, according to the current setting of the caseless flag. The REQ_CASELESS leaves the lower 28 bit empty. It is added into the firstchar or reqchar variables to record the case status of the value. This is used only for ASCII characters. */ req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0; /* Switch on next character until the end of the branch */ for (;; ptr++) { BOOL negate_class; BOOL should_flip_negation; BOOL possessive_quantifier; BOOL is_quantifier; BOOL is_recurse; BOOL reset_bracount; int class_has_8bitchar; int class_single_char; int newoptions; int recno; int refsign; int skipbytes; int subreqchar; int subfirstchar; int terminator; int mclength; int tempbracount; pcre_uchar mcbuffer[8]; /* Get next character in the pattern */ c = *ptr; /* If we are at the end of a nested substitution, revert to the outer level string. Nesting only happens one level deep. */ if (c == 0 && nestptr != NULL) { ptr = nestptr; nestptr = NULL; c = *ptr; } /* If we are in the pre-compile phase, accumulate the length used for the previous cycle of this loop. */ if (lengthptr != NULL) { #ifdef PCRE_DEBUG if (code > cd->hwm) cd->hwm = code; /* High water info */ #endif if (code > cd->start_workspace + cd->workspace_size - WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ { *errorcodeptr = ERR52; goto FAILED; } /* There is at least one situation where code goes backwards: this is the case of a zero quantifier after a class (e.g. [ab]{0}). At compile time, the class is simply eliminated. However, it is created first, so we have to allow memory for it. Therefore, don't ever reduce the length at this point. */ if (code < last_code) code = last_code; /* Paranoid check for integer overflow */ if (OFLOW_MAX - *lengthptr < code - last_code) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += (int)(code - last_code); DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr, (int)(code - last_code), c, c)); /* If "previous" is set and it is not at the start of the work space, move it back to there, in order to avoid filling up the work space. Otherwise, if "previous" is NULL, reset the current code pointer to the start. */ if (previous != NULL) { if (previous > orig_code) { memmove(orig_code, previous, IN_UCHARS(code - previous)); code -= previous - orig_code; previous = orig_code; } } else code = orig_code; /* Remember where this code item starts so we can pick up the length next time round. */ last_code = code; } /* In the real compile phase, just check the workspace used by the forward reference list. */ else if (cd->hwm > cd->start_workspace + cd->workspace_size - WORK_SIZE_SAFETY_MARGIN) { *errorcodeptr = ERR52; goto FAILED; } /* If in \Q...\E, check for the end; if not, we have a literal */ if (inescq && c != 0) { if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) { inescq = FALSE; ptr++; continue; } else { if (previous_callout != NULL) { if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ complete_callout(previous_callout, ptr, cd); previous_callout = NULL; } if ((options & PCRE_AUTO_CALLOUT) != 0) { previous_callout = code; code = auto_callout(code, ptr, cd); } goto NORMAL_CHAR; } } /* Fill in length of a previous callout, except when the next thing is a quantifier. */ is_quantifier = c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK || (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1)); if (!is_quantifier && previous_callout != NULL && after_manual_callout-- <= 0) { if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ complete_callout(previous_callout, ptr, cd); previous_callout = NULL; } /* In extended mode, skip white space and comments. */ if ((options & PCRE_EXTENDED) != 0) { if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue; if (c == CHAR_NUMBER_SIGN) { ptr++; while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; #ifdef SUPPORT_UTF if (utf) FORWARDCHAR(ptr); #endif } if (*ptr != 0) continue; /* Else fall through to handle end of string */ c = 0; } } /* No auto callout for quantifiers. */ if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier) { previous_callout = code; code = auto_callout(code, ptr, cd); } switch(c) { /* ===================================================================*/ case 0: /* The branch terminates at string end */ case CHAR_VERTICAL_LINE: /* or | or ) */ case CHAR_RIGHT_PARENTHESIS: *firstcharptr = firstchar; *reqcharptr = reqchar; *codeptr = code; *ptrptr = ptr; if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < code - last_code) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += (int)(code - last_code); /* To include callout length */ DPRINTF((">> end branch\n")); } return TRUE; /* ===================================================================*/ /* Handle single-character metacharacters. In multiline mode, ^ disables the setting of any following char as a first character. */ case CHAR_CIRCUMFLEX_ACCENT: previous = NULL; if ((options & PCRE_MULTILINE) != 0) { if (firstchar == REQ_UNSET) firstchar = REQ_NONE; *code++ = OP_CIRCM; } else *code++ = OP_CIRC; break; case CHAR_DOLLAR_SIGN: previous = NULL; *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL; break; /* There can never be a first char if '.' is first, whatever happens about repeats. The value of reqchar doesn't change either. */ case CHAR_DOT: if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; zeroreqchar = reqchar; previous = code; *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY; break; /* ===================================================================*/ /* Character classes. If the included characters are all < 256, we build a 32-byte bitmap of the permitted characters, except in the special case where there is only one such character. For negated classes, we build the map as usual, then invert it at the end. However, we use a different opcode so that data characters > 255 can be handled correctly. If the class contains characters outside the 0-255 range, a different opcode is compiled. It may optionally have a bit map for characters < 256, but those above are are explicitly listed afterwards. A flag byte tells whether the bitmap is present, and whether this is a negated class or not. In JavaScript compatibility mode, an isolated ']' causes an error. In default (Perl) mode, it is treated as a data character. */ case CHAR_RIGHT_SQUARE_BRACKET: if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0) { *errorcodeptr = ERR64; goto FAILED; } goto NORMAL_CHAR; case CHAR_LEFT_SQUARE_BRACKET: previous = code; /* PCRE supports POSIX class stuff inside a class. Perl gives an error if they are encountered at the top level, so we'll do that too. */ if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr)) { *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR13 : ERR31; goto FAILED; } /* If the first character is '^', set the negation flag and skip it. Also, if the first few characters (either before or after ^) are \Q\E or \E we skip them too. This makes for compatibility with Perl. */ negate_class = FALSE; for (;;) { c = *(++ptr); if (c == CHAR_BACKSLASH) { if (ptr[1] == CHAR_E) ptr++; else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) ptr += 3; else break; } else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) negate_class = TRUE; else break; } /* Empty classes are allowed in JavaScript compatibility mode. Otherwise, an initial ']' is taken as a data character -- the code below handles that. In JS mode, [] must always fail, so generate OP_FAIL, whereas [^] must match any character, so generate OP_ALLANY. */ if (c == CHAR_RIGHT_SQUARE_BRACKET && (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0) { *code++ = negate_class? OP_ALLANY : OP_FAIL; if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; break; } /* If a class contains a negative special such as \S, we need to flip the negation flag at the end, so that support for characters > 255 works correctly (they are all included in the class). */ should_flip_negation = FALSE; /* For optimization purposes, we track some properties of the class. class_has_8bitchar will be non-zero, if the class contains at least one < 256 character. class_single_char will be 1 if the class contains only a single character. */ class_has_8bitchar = 0; class_single_char = 0; /* Initialize the 32-char bit map to all zeros. We build the map in a temporary bit of memory, in case the class contains only 1 character (less than 256), because in that case the compiled code doesn't use the bit map. */ memset(classbits, 0, 32 * sizeof(pcre_uint8)); #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 xclass = FALSE; /* No chars >= 256 */ class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */ class_uchardata_base = class_uchardata; /* For resetting in pass 1 */ #endif /* Process characters until ] is reached. By writing this as a "do" it means that an initial ] is taken as a data character. At the start of the loop, c contains the first byte of the character. */ if (c != 0) do { const pcre_uchar *oldptr; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(c)) { /* Braces are required because the */ GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ } #endif #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 /* In the pre-compile phase, accumulate the length of any extra data and reset the pointer. This is so that very large classes that contain a zillion > 255 characters no longer overwrite the work space (which is on the stack). */ if (lengthptr != NULL) { *lengthptr += class_uchardata - class_uchardata_base; class_uchardata = class_uchardata_base; } #endif /* Inside \Q...\E everything is literal except \E */ if (inescq) { if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */ { inescq = FALSE; /* Reset literal state */ ptr++; /* Skip the 'E' */ continue; /* Carry on with next */ } goto CHECK_RANGE; /* Could be range if \E follows */ } /* Handle POSIX class names. Perl allows a negation extension of the form [:^name:]. A square bracket that doesn't match the syntax is treated as a literal. We also recognize the POSIX constructions [.ch.] and [=ch=] ("collating elements") and fault them, as Perl 5.6 and 5.8 do. */ if (c == CHAR_LEFT_SQUARE_BRACKET && (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr)) { BOOL local_negate = FALSE; int posix_class, taboffset, tabopt; register const pcre_uint8 *cbits = cd->cbits; pcre_uint8 pbits[32]; if (ptr[1] != CHAR_COLON) { *errorcodeptr = ERR31; goto FAILED; } ptr += 2; if (*ptr == CHAR_CIRCUMFLEX_ACCENT) { local_negate = TRUE; should_flip_negation = TRUE; /* Note negative special */ ptr++; } posix_class = check_posix_name(ptr, (int)(tempptr - ptr)); if (posix_class < 0) { *errorcodeptr = ERR30; goto FAILED; } /* If matching is caseless, upper and lower are converted to alpha. This relies on the fact that the class table starts with alpha, lower, upper as the first 3 entries. */ if ((options & PCRE_CASELESS) != 0 && posix_class <= 2) posix_class = 0; /* When PCRE_UCP is set, some of the POSIX classes are converted to different escape sequences that use Unicode properties. */ #ifdef SUPPORT_UCP if ((options & PCRE_UCP) != 0) { int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0); if (posix_substitutes[pc] != NULL) { nestptr = tempptr + 1; ptr = posix_substitutes[pc] - 1; continue; } } #endif /* In the non-UCP case, we build the bit map for the POSIX class in a chunk of local store because we may be adding and subtracting from it, and we don't want to subtract bits that may be in the main map already. At the end we or the result into the bit map that is being built. */ posix_class *= 3; /* Copy in the first table (always present) */ memcpy(pbits, cbits + posix_class_maps[posix_class], 32 * sizeof(pcre_uint8)); /* If there is a second table, add or remove it as required. */ taboffset = posix_class_maps[posix_class + 1]; tabopt = posix_class_maps[posix_class + 2]; if (taboffset >= 0) { if (tabopt >= 0) for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset]; else for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset]; } /* Not see if we need to remove any special characters. An option value of 1 removes vertical space and 2 removes underscore. */ if (tabopt < 0) tabopt = -tabopt; if (tabopt == 1) pbits[1] &= ~0x3c; else if (tabopt == 2) pbits[11] &= 0x7f; /* Add the POSIX table or its complement into the main table that is being built and we are done. */ if (local_negate) for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c]; else for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; ptr = tempptr + 1; /* Every class contains at least one < 256 characters. */ class_has_8bitchar = 1; /* Every class contains at least two characters. */ class_single_char = 2; continue; /* End of POSIX syntax handling */ } /* Backslash may introduce a single character, or it may introduce one of the specials, which just set a flag. The sequence \b is a special case. Inside a class (and only there) it is treated as backspace. We assume that other escapes have more than one character in them, so speculatively set both class_has_8bitchar and class_single_char bigger than one. Unrecognized escapes fall through and are either treated as literal characters (by default), or are faulted if PCRE_EXTRA is set. */ if (c == CHAR_BACKSLASH) { c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE); if (*errorcodeptr != 0) goto FAILED; if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ else if (-c == ESC_N) /* \N is not supported in a class */ { *errorcodeptr = ERR71; goto FAILED; } else if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) { ptr += 2; /* avoid empty string */ } else inescq = TRUE; continue; } else if (-c == ESC_E) continue; /* Ignore orphan \E */ if (c < 0) { register const pcre_uint8 *cbits = cd->cbits; /* Every class contains at least two < 256 characters. */ class_has_8bitchar++; /* Every class contains at least two characters. */ class_single_char += 2; switch (-c) { #ifdef SUPPORT_UCP case ESC_du: /* These are the values given for \d etc */ case ESC_DU: /* when PCRE_UCP is set. We replace the */ case ESC_wu: /* escape sequence with an appropriate \p */ case ESC_WU: /* or \P to test Unicode properties instead */ case ESC_su: /* of the default ASCII testing. */ case ESC_SU: nestptr = ptr; ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */ class_has_8bitchar--; /* Undo! */ continue; #endif case ESC_d: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit]; continue; case ESC_D: should_flip_negation = TRUE; for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit]; continue; case ESC_w: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word]; continue; case ESC_W: should_flip_negation = TRUE; for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; continue; /* Perl 5.004 onwards omits VT from \s, but we must preserve it if it was previously set by something earlier in the character class. */ case ESC_s: classbits[0] |= cbits[cbit_space]; classbits[1] |= cbits[cbit_space+1] & ~0x08; for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; continue; case ESC_S: should_flip_negation = TRUE; for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */ continue; case ESC_h: SETBIT(classbits, 0x09); /* VT */ SETBIT(classbits, 0x20); /* SPACE */ SETBIT(classbits, 0xa0); /* NSBP */ #ifndef COMPILE_PCRE8 xclass = TRUE; *class_uchardata++ = XCL_SINGLE; *class_uchardata++ = 0x1680; *class_uchardata++ = XCL_SINGLE; *class_uchardata++ = 0x180e; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x2000; *class_uchardata++ = 0x200a; *class_uchardata++ = XCL_SINGLE; *class_uchardata++ = 0x202f; *class_uchardata++ = XCL_SINGLE; *class_uchardata++ = 0x205f; *class_uchardata++ = XCL_SINGLE; *class_uchardata++ = 0x3000; #elif defined SUPPORT_UTF if (utf) { xclass = TRUE; *class_uchardata++ = XCL_SINGLE; class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata); *class_uchardata++ = XCL_SINGLE; class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata); class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata); *class_uchardata++ = XCL_SINGLE; class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata); *class_uchardata++ = XCL_SINGLE; class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata); *class_uchardata++ = XCL_SINGLE; class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata); } #endif continue; case ESC_H: for (c = 0; c < 32; c++) { int x = 0xff; switch (c) { case 0x09/8: x ^= 1 << (0x09%8); break; case 0x20/8: x ^= 1 << (0x20%8); break; case 0xa0/8: x ^= 1 << (0xa0%8); break; default: break; } classbits[c] |= x; } #ifndef COMPILE_PCRE8 xclass = TRUE; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x0100; *class_uchardata++ = 0x167f; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x1681; *class_uchardata++ = 0x180d; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x180f; *class_uchardata++ = 0x1fff; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x200b; *class_uchardata++ = 0x202e; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x2030; *class_uchardata++ = 0x205e; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x2060; *class_uchardata++ = 0x2fff; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x3001; #ifdef SUPPORT_UTF if (utf) class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); else #endif *class_uchardata++ = 0xffff; #elif defined SUPPORT_UTF if (utf) { xclass = TRUE; *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata); class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata); class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata); class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata); class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata); class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata); class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); } #endif continue; case ESC_v: SETBIT(classbits, 0x0a); /* LF */ SETBIT(classbits, 0x0b); /* VT */ SETBIT(classbits, 0x0c); /* FF */ SETBIT(classbits, 0x0d); /* CR */ SETBIT(classbits, 0x85); /* NEL */ #ifndef COMPILE_PCRE8 xclass = TRUE; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x2028; *class_uchardata++ = 0x2029; #elif defined SUPPORT_UTF if (utf) { xclass = TRUE; *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata); class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata); } #endif continue; case ESC_V: for (c = 0; c < 32; c++) { int x = 0xff; switch (c) { case 0x0a/8: x ^= 1 << (0x0a%8); x ^= 1 << (0x0b%8); x ^= 1 << (0x0c%8); x ^= 1 << (0x0d%8); break; case 0x85/8: x ^= 1 << (0x85%8); break; default: break; } classbits[c] |= x; } #ifndef COMPILE_PCRE8 xclass = TRUE; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x0100; *class_uchardata++ = 0x2027; *class_uchardata++ = XCL_RANGE; *class_uchardata++ = 0x202a; #ifdef SUPPORT_UTF if (utf) class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); else #endif *class_uchardata++ = 0xffff; #elif defined SUPPORT_UTF if (utf) { xclass = TRUE; *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata); *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata); class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); } #endif continue; #ifdef SUPPORT_UCP case ESC_p: case ESC_P: { BOOL negated; int pdata; int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); if (ptype < 0) goto FAILED; xclass = TRUE; *class_uchardata++ = ((-c == ESC_p) != negated)? XCL_PROP : XCL_NOTPROP; *class_uchardata++ = ptype; *class_uchardata++ = pdata; class_has_8bitchar--; /* Undo! */ continue; } #endif /* Unrecognized escapes are faulted if PCRE is running in its strict mode. By default, for compatibility with Perl, they are treated as literals. */ default: if ((options & PCRE_EXTRA) != 0) { *errorcodeptr = ERR7; goto FAILED; } class_has_8bitchar--; /* Undo the speculative increase. */ class_single_char -= 2; /* Undo the speculative increase. */ c = *ptr; /* Get the final character and fall through */ break; } } /* Fall through if we have a single character (c >= 0). This may be greater than 256. */ } /* End of backslash handling */ /* A single character may be followed by '-' to form a range. However, Perl does not permit ']' to be the end of the range. A '-' character at the end is treated as a literal. Perl ignores orphaned \E sequences entirely. The code for handling \Q and \E is messy. */ CHECK_RANGE: while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) { inescq = FALSE; ptr += 2; } oldptr = ptr; /* Remember \r or \n */ if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; /* Check for range */ if (!inescq && ptr[1] == CHAR_MINUS) { int d; ptr += 2; while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2; /* If we hit \Q (not followed by \E) at this point, go into escaped mode. */ while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q) { ptr += 2; if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) { ptr += 2; continue; } inescq = TRUE; break; } if (*ptr == 0 || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET)) { ptr = oldptr; goto LONE_SINGLE_CHARACTER; } #ifdef SUPPORT_UTF if (utf) { /* Braces are required because the */ GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ } else #endif d = *ptr; /* Not UTF-8 mode */ /* The second part of a range can be a single-character escape, but not any of the other escapes. Perl 5.6 treats a hyphen as a literal in such circumstances. */ if (!inescq && d == CHAR_BACKSLASH) { d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE); if (*errorcodeptr != 0) goto FAILED; /* \b is backspace; any other special means the '-' was literal */ if (d < 0) { if (d == -ESC_b) d = CHAR_BS; else { ptr = oldptr; goto LONE_SINGLE_CHARACTER; /* A few lines below */ } } } /* Check that the two values are in the correct order. Optimize one-character ranges */ if (d < c) { *errorcodeptr = ERR8; goto FAILED; } if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */ /* Remember \r or \n */ if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; /* Since we found a character range, single character optimizations cannot be done anymore. */ class_single_char = 2; /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless matching, we have to use an XCLASS with extra data items. Caseless matching for characters > 127 is available only if UCP support is available. */ #if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127))) #elif defined SUPPORT_UTF if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) #elif !(defined COMPILE_PCRE8) if (d > 255) #endif #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) { xclass = TRUE; /* With UCP support, we can find the other case equivalents of the relevant characters. There may be several ranges. Optimize how they fit with the basic range. */ #ifdef SUPPORT_UCP #ifndef COMPILE_PCRE8 if (utf && (options & PCRE_CASELESS) != 0) #else if ((options & PCRE_CASELESS) != 0) #endif { unsigned int occ, ocd; unsigned int cc = c; unsigned int origd = d; while (get_othercase_range(&cc, origd, &occ, &ocd)) { if (occ >= (unsigned int)c && ocd <= (unsigned int)d) continue; /* Skip embedded ranges */ if (occ < (unsigned int)c && ocd >= (unsigned int)c - 1) /* Extend the basic range */ { /* if there is overlap, */ c = occ; /* noting that if occ < c */ continue; /* we can't have ocd > d */ } /* because a subrange is */ if (ocd > (unsigned int)d && occ <= (unsigned int)d + 1) /* always shorter than */ { /* the basic range. */ d = ocd; continue; } if (occ == ocd) { *class_uchardata++ = XCL_SINGLE; } else { *class_uchardata++ = XCL_RANGE; class_uchardata += PRIV(ord2utf)(occ, class_uchardata); } class_uchardata += PRIV(ord2utf)(ocd, class_uchardata); } } #endif /* SUPPORT_UCP */ /* Now record the original range, possibly modified for UCP caseless overlapping ranges. */ *class_uchardata++ = XCL_RANGE; #ifdef SUPPORT_UTF #ifndef COMPILE_PCRE8 if (utf) { class_uchardata += PRIV(ord2utf)(c, class_uchardata); class_uchardata += PRIV(ord2utf)(d, class_uchardata); } else { *class_uchardata++ = c; *class_uchardata++ = d; } #else class_uchardata += PRIV(ord2utf)(c, class_uchardata); class_uchardata += PRIV(ord2utf)(d, class_uchardata); #endif #else /* SUPPORT_UTF */ *class_uchardata++ = c; *class_uchardata++ = d; #endif /* SUPPORT_UTF */ /* With UCP support, we are done. Without UCP support, there is no caseless matching for UTF characters > 127; we can use the bit map for the smaller ones. As for 16 bit characters without UTF, we can still use */ #ifdef SUPPORT_UCP #ifndef COMPILE_PCRE8 if (utf) #endif continue; /* With next character in the class */ #endif /* SUPPORT_UCP */ #if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8) if (utf) { if ((options & PCRE_CASELESS) == 0 || c > 127) continue; /* Adjust upper limit and fall through to set up the map */ d = 127; } else { if (c > 255) continue; /* Adjust upper limit and fall through to set up the map */ d = 255; } #elif defined SUPPORT_UTF && !defined(SUPPORT_UCP) if ((options & PCRE_CASELESS) == 0 || c > 127) continue; /* Adjust upper limit and fall through to set up the map */ d = 127; #else if (c > 255) continue; /* Adjust upper limit and fall through to set up the map */ d = 255; #endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */ } #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ /* We use the bit map for 8 bit mode, or when the characters fall partially or entirely to [0-255] ([0-127] for UCP) ranges. */ class_has_8bitchar = 1; /* We can save a bit of time by skipping this in the pre-compile. */ if (lengthptr == NULL) for (; c <= d; c++) { classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { int uc = cd->fcc[c]; /* flip case */ classbits[uc/8] |= (1 << (uc&7)); } } continue; /* Go get the next char in the class */ } /* Handle a lone single character - we can get here for a normal non-escape char, or after \ that introduces a single character or for an apparent range that isn't. */ LONE_SINGLE_CHARACTER: /* Only the value of 1 matters for class_single_char. */ if (class_single_char < 2) class_single_char++; /* If class_charcount is 1, we saw precisely one character. As long as there was no use of \p or \P, in other words, no use of any XCLASS features, we can optimize. The optimization throws away the bit map. We turn the item into a 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative. In the positive case, it can cause firstchar to be set. Otherwise, there can be no first char if this item is first, whatever repeat count may follow. In the case of reqchar, save the previous value for reinstating. */ if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { ptr++; zeroreqchar = reqchar; if (negate_class) { if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT; #ifdef SUPPORT_UTF if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) code += PRIV(ord2utf)(c, code); else #endif *code++ = c; goto NOT_CHAR; } /* For a single, positive character, get the value into mcbuffer, and then we can handle this with the normal one-character code. */ #ifdef SUPPORT_UTF if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) mclength = PRIV(ord2utf)(c, mcbuffer); else #endif { mcbuffer[0] = c; mclength = 1; } goto ONE_CHAR; } /* End of 1-char optimization */ /* Handle a character that cannot go in the bit map. */ #if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127))) #elif defined SUPPORT_UTF if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) #elif !(defined COMPILE_PCRE8) if (c > 255) #endif #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) { xclass = TRUE; *class_uchardata++ = XCL_SINGLE; #ifdef SUPPORT_UTF #ifndef COMPILE_PCRE8 /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ if (!utf) *class_uchardata++ = c; else #endif class_uchardata += PRIV(ord2utf)(c, class_uchardata); #else /* SUPPORT_UTF */ *class_uchardata++ = c; #endif /* SUPPORT_UTF */ #ifdef SUPPORT_UCP #ifdef COMPILE_PCRE8 if ((options & PCRE_CASELESS) != 0) #else /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ if (utf && (options & PCRE_CASELESS) != 0) #endif { unsigned int othercase; if ((int)(othercase = UCD_OTHERCASE(c)) != c) { *class_uchardata++ = XCL_SINGLE; class_uchardata += PRIV(ord2utf)(othercase, class_uchardata); } } #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF || COMPILE_PCRE16 */ /* Handle a single-byte character */ { class_has_8bitchar = 1; classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { c = cd->fcc[c]; /* flip case */ classbits[c/8] |= (1 << (c&7)); } } } /* Loop until ']' reached. This "while" is the end of the "do" far above. If we are at the end of an internal nested string, revert to the outer string. */ while (((c = *(++ptr)) != 0 || (nestptr != NULL && (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != 0)) && (c != CHAR_RIGHT_SQUARE_BRACKET || inescq)); /* Check for missing terminating ']' */ if (c == 0) { *errorcodeptr = ERR6; goto FAILED; } /* If this is the first thing in the branch, there can be no first char setting, whatever the repeat count. Any reqchar setting must remain unchanged after any kind of repeat. */ if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; zeroreqchar = reqchar; /* If there are characters with values > 255, we have to compile an extended class, with its own opcode, unless there was a negated special such as \S in the class, and PCRE_UCP is not set, because in that case all characters > 255 are in the class, so any that were explicitly given as well can be ignored. If (when there are explicit characters > 255 that must be listed) there are no characters < 256, we can omit the bitmap in the actual compiled code. */ #ifdef SUPPORT_UTF if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0)) #elif !defined COMPILE_PCRE8 if (xclass && !should_flip_negation) #endif #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 { *class_uchardata++ = XCL_END; /* Marks the end of extra data */ *code++ = OP_XCLASS; code += LINK_SIZE; *code = negate_class? XCL_NOT:0; /* If the map is required, move up the extra data to make room for it; otherwise just move the code pointer to the end of the extra data. */ if (class_has_8bitchar > 0) { *code++ |= XCL_MAP; memmove(code + (32 / sizeof(pcre_uchar)), code, IN_UCHARS(class_uchardata - code)); memcpy(code, classbits, 32); code = class_uchardata + (32 / sizeof(pcre_uchar)); } else code = class_uchardata; /* Now fill in the complete length of the item */ PUT(previous, 1, (int)(code - previous)); break; /* End of class handling */ } #endif /* If there are no characters > 255, or they are all to be included or excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the whole class was negated and whether there were negative specials such as \S (non-UCP) in the class. Then copy the 32-byte map into the code vector, negating it if necessary. */ *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; if (lengthptr == NULL) /* Save time in the pre-compile phase */ { if (negate_class) for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; memcpy(code, classbits, 32); } code += 32 / sizeof(pcre_uchar); NOT_CHAR: break; /* ===================================================================*/ /* Various kinds of repeat; '{' is not necessarily a quantifier, but this has been tested above. */ case CHAR_LEFT_CURLY_BRACKET: if (!is_quantifier) goto NORMAL_CHAR; ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr); if (*errorcodeptr != 0) goto FAILED; goto REPEAT; case CHAR_ASTERISK: repeat_min = 0; repeat_max = -1; goto REPEAT; case CHAR_PLUS: repeat_min = 1; repeat_max = -1; goto REPEAT; case CHAR_QUESTION_MARK: repeat_min = 0; repeat_max = 1; REPEAT: if (previous == NULL) { *errorcodeptr = ERR9; goto FAILED; } if (repeat_min == 0) { firstchar = zerofirstchar; /* Adjust for zero repeat */ reqchar = zeroreqchar; /* Ditto */ } /* Remember whether this is a variable length repeat */ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; op_type = 0; /* Default single-char op codes */ possessive_quantifier = FALSE; /* Default not possessive quantifier */ /* Save start of previous item, in case we have to move it up in order to insert something before it. */ tempcode = previous; /* If the next character is '+', we have a possessive quantifier. This implies greediness, whatever the setting of the PCRE_UNGREEDY option. If the next character is '?' this is a minimizing repeat, by default, but if PCRE_UNGREEDY is set, it works the other way round. We change the repeat type to the non-default. */ if (ptr[1] == CHAR_PLUS) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; ptr++; } else if (ptr[1] == CHAR_QUESTION_MARK) { repeat_type = greedy_non_default; ptr++; } else repeat_type = greedy_default; /* If previous was a recursion call, wrap it in atomic brackets so that previous becomes the atomic group. All recursions were so wrapped in the past, but it no longer happens for non-repeated recursions. In fact, the repeated ones could be re-implemented independently so as not to need this, but for the moment we rely on the code for repeating groups. */ if (*previous == OP_RECURSE) { memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE)); *previous = OP_ONCE; PUT(previous, 1, 2 + 2*LINK_SIZE); previous[2 + 2*LINK_SIZE] = OP_KET; PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE); code += 2 + 2 * LINK_SIZE; length_prevgroup = 3 + 3*LINK_SIZE; /* When actually compiling, we need to check whether this was a forward reference, and if so, adjust the offset. */ if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE) { int offset = GET(cd->hwm, -LINK_SIZE); if (offset == previous + 1 - cd->start_code) PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE); } } /* Now handle repetition for the different types of item. */ /* If previous was a character or negated character match, abolish the item and generate a repeat item instead. If a char item has a minimum of more than one, ensure that it is set in reqchar - it might not be if a sequence such as x{3} is the first thing in a branch because the x will have gone into firstchar instead. */ if (*previous == OP_CHAR || *previous == OP_CHARI || *previous == OP_NOT || *previous == OP_NOTI) { switch (*previous) { default: /* Make compiler happy. */ case OP_CHAR: op_type = OP_STAR - OP_STAR; break; case OP_CHARI: op_type = OP_STARI - OP_STAR; break; case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break; case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break; } /* Deal with UTF characters that take up more than one character. It's easier to write this out separately than try to macrify it. Use c to hold the length of the character in bytes, plus UTF_LENGTH to flag that it's a length rather than a small character. */ #ifdef SUPPORT_UTF if (utf && NOT_FIRSTCHAR(code[-1])) { pcre_uchar *lastchar = code - 1; BACKCHAR(lastchar); c = (int)(code - lastchar); /* Length of UTF-8 character */ memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */ c |= UTF_LENGTH; /* Flag c as a length */ } else #endif /* SUPPORT_UTF */ /* Handle the case of a single charater - either with no UTF support, or with UTF disabled, or for a single character UTF character. */ { c = code[-1]; if (*previous <= OP_CHARI && repeat_min > 1) reqchar = c | req_caseopt | cd->req_varyopt; } /* If the repetition is unlimited, it pays to see if the next thing on the line is something that cannot possibly match this character. If so, automatically possessifying this item gains some performance in the case where the match fails. */ if (!possessive_quantifier && repeat_max < 0 && check_auto_possessive(previous, utf, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; } goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ } /* If previous was a character type match (\d or similar), abolish it and create a suitable repeat item. The code is shared with single-character repeats by setting op_type to add a suitable offset into repeat_type. Note the the Unicode property types will be present only when SUPPORT_UCP is defined, but we don't wrap the little bits of code here because it just makes it horribly messy. */ else if (*previous < OP_EODN) { pcre_uchar *oldcode; int prop_type, prop_value; op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ c = *previous; if (!possessive_quantifier && repeat_max < 0 && check_auto_possessive(previous, utf, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; } OUTPUT_SINGLE_REPEAT: if (*previous == OP_PROP || *previous == OP_NOTPROP) { prop_type = previous[1]; prop_value = previous[2]; } else prop_type = prop_value = -1; oldcode = code; code = previous; /* Usually overwrite previous item */ /* If the maximum is zero then the minimum must also be zero; Perl allows this case, so we do too - by simply omitting the item altogether. */ if (repeat_max == 0) goto END_REPEAT; /*--------------------------------------------------------------------*/ /* This code is obsolete from release 8.00; the restriction was finally removed: */ /* All real repeats make it impossible to handle partial matching (maybe one day we will be able to remove this restriction). */ /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */ /*--------------------------------------------------------------------*/ /* Combine the op_type with the repeat_type */ repeat_type += op_type; /* A minimum of zero is handled either as the special case * or ?, or as an UPTO, with the maximum given. */ if (repeat_min == 0) { if (repeat_max == -1) *code++ = OP_STAR + repeat_type; else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type; else { *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max); } } /* A repeat minimum of 1 is optimized into some special cases. If the maximum is unlimited, we use OP_PLUS. Otherwise, the original item is left in place and, if the maximum is greater than 1, we use OP_UPTO with one less than the maximum. */ else if (repeat_min == 1) { if (repeat_max == -1) *code++ = OP_PLUS + repeat_type; else { code = oldcode; /* leave previous item in place */ if (repeat_max == 1) goto END_REPEAT; *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max - 1); } } /* The case {n,n} is just an EXACT, while the general case {n,m} is handled as an EXACT followed by an UPTO. */ else { *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */ PUT2INC(code, 0, repeat_min); /* If the maximum is unlimited, insert an OP_STAR. Before doing so, we have to insert the character for the previous code. For a repeated Unicode property match, there are two extra bytes that define the required property. In UTF-8 mode, long characters have their length in c, with the UTF_LENGTH bit as a flag. */ if (repeat_max < 0) { #ifdef SUPPORT_UTF if (utf && (c & UTF_LENGTH) != 0) { memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else #endif { *code++ = c; if (prop_type >= 0) { *code++ = prop_type; *code++ = prop_value; } } *code++ = OP_STAR + repeat_type; } /* Else insert an UPTO if the max is greater than the min, again preceded by the character, for the previously inserted code. If the UPTO is just for 1 instance, we can use QUERY instead. */ else if (repeat_max != repeat_min) { #ifdef SUPPORT_UTF if (utf && (c & UTF_LENGTH) != 0) { memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else #endif *code++ = c; if (prop_type >= 0) { *code++ = prop_type; *code++ = prop_value; } repeat_max -= repeat_min; if (repeat_max == 1) { *code++ = OP_QUERY + repeat_type; } else { *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max); } } } /* The character or character type itself comes last in all cases. */ #ifdef SUPPORT_UTF if (utf && (c & UTF_LENGTH) != 0) { memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else #endif *code++ = c; /* For a repeated Unicode property match, there are two extra bytes that define the required property. */ #ifdef SUPPORT_UCP if (prop_type >= 0) { *code++ = prop_type; *code++ = prop_value; } #endif } /* If previous was a character class or a back reference, we put the repeat stuff after it, but just skip the item if the repeat was {0,0}. */ else if (*previous == OP_CLASS || *previous == OP_NCLASS || #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 *previous == OP_XCLASS || #endif *previous == OP_REF || *previous == OP_REFI) { if (repeat_max == 0) { code = previous; goto END_REPEAT; } /*--------------------------------------------------------------------*/ /* This code is obsolete from release 8.00; the restriction was finally removed: */ /* All real repeats make it impossible to handle partial matching (maybe one day we will be able to remove this restriction). */ /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */ /*--------------------------------------------------------------------*/ if (repeat_min == 0 && repeat_max == -1) *code++ = OP_CRSTAR + repeat_type; else if (repeat_min == 1 && repeat_max == -1) *code++ = OP_CRPLUS + repeat_type; else if (repeat_min == 0 && repeat_max == 1) *code++ = OP_CRQUERY + repeat_type; else { *code++ = OP_CRRANGE + repeat_type; PUT2INC(code, 0, repeat_min); if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */ PUT2INC(code, 0, repeat_max); } } /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" bracket opcodes such as BRA and CBRA, as this is the place where they get converted into the more special varieties such as BRAPOS and SBRA. A test for >= OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK, ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow repetition of assertions, but now it does, for Perl compatibility. */ else if (*previous >= OP_ASSERT && *previous <= OP_COND) { register int i; int len = (int)(code - previous); pcre_uchar *bralink = NULL; pcre_uchar *brazeroptr = NULL; /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so we just ignore the repeat. */ if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF) goto END_REPEAT; /* There is no sense in actually repeating assertions. The only potential use of repetition is in cases when the assertion is optional. Therefore, if the minimum is greater than zero, just ignore the repeat. If the maximum is not not zero or one, set it to 1. */ if (*previous < OP_ONCE) /* Assertion */ { if (repeat_min > 0) goto END_REPEAT; if (repeat_max < 0 || repeat_max > 1) repeat_max = 1; } /* The case of a zero minimum is special because of the need to stick OP_BRAZERO in front of it, and because the group appears once in the data, whereas in other cases it appears the minimum number of times. For this reason, it is simplest to treat this case separately, as otherwise the code gets far too messy. There are several special subcases when the minimum is zero. */ if (repeat_min == 0) { /* If the maximum is also zero, we used to just omit the group from the output altogether, like this: ** if (repeat_max == 0) ** { ** code = previous; ** goto END_REPEAT; ** } However, that fails when a group or a subgroup within it is referenced as a subroutine from elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it so that it is skipped on execution. As we don't have a list of which groups are referenced, we cannot do this selectively. If the maximum is 1 or unlimited, we just have to stick in the BRAZERO and do no more at this point. However, we do need to adjust any OP_RECURSE calls inside the group that refer to the group itself or any internal or forward referenced group, because the offset is from the start of the whole regex. Temporarily terminate the pattern while doing this. */ if (repeat_max <= 1) /* Covers 0, 1, and unlimited */ { *code = OP_END; adjust_recurse(previous, 1, utf, cd, save_hwm); memmove(previous + 1, previous, IN_UCHARS(len)); code++; if (repeat_max == 0) { *previous++ = OP_SKIPZERO; goto END_REPEAT; } brazeroptr = previous; /* Save for possessive optimizing */ *previous++ = OP_BRAZERO + repeat_type; } /* If the maximum is greater than 1 and limited, we have to replicate in a nested fashion, sticking OP_BRAZERO before each set of brackets. The first one has to be handled carefully because it's the original copy, which has to be moved up. The remainder can be handled by code that is common with the non-zero minimum case below. We have to adjust the value or repeat_max, since one less copy is required. Once again, we may have to adjust any OP_RECURSE calls inside the group. */ else { int offset; *code = OP_END; adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm); memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len)); code += 2 + LINK_SIZE; *previous++ = OP_BRAZERO + repeat_type; *previous++ = OP_BRA; /* We chain together the bracket offset fields that have to be filled in later when the ends of the brackets are reached. */ offset = (bralink == NULL)? 0 : (int)(previous - bralink); bralink = previous; PUTINC(previous, 0, offset); } repeat_max--; } /* If the minimum is greater than zero, replicate the group as many times as necessary, and adjust the maximum to the number of subsequent copies that we need. If we set a first char from the group, and didn't set a required char, copy the latter from the former. If there are any forward reference subroutine calls in the group, there will be entries on the workspace list; replicate these with an appropriate increment. */ else { if (repeat_min > 1) { /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. Do some paranoid checks for potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit integer type when available, otherwise double. */ if (lengthptr != NULL) { int delta = (repeat_min - 1)*length_prevgroup; if ((INT64_OR_DOUBLE)(repeat_min - 1)* (INT64_OR_DOUBLE)length_prevgroup > (INT64_OR_DOUBLE)INT_MAX || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += delta; } /* This is compiling for real. If there is a set first byte for the group, and we have not yet set a "required byte", set it. Make sure there is enough workspace for copying forward references before doing the copy. */ else { if (groupsetfirstchar && reqchar < 0) reqchar = firstchar; for (i = 1; i < repeat_min; i++) { pcre_uchar *hc; pcre_uchar *this_hwm = cd->hwm; memcpy(code, previous, IN_UCHARS(len)); while (cd->hwm > cd->start_workspace + cd->workspace_size - WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm)) { int save_offset = save_hwm - cd->start_workspace; int this_offset = this_hwm - cd->start_workspace; *errorcodeptr = expand_workspace(cd); if (*errorcodeptr != 0) goto FAILED; save_hwm = (pcre_uchar *)cd->start_workspace + save_offset; this_hwm = (pcre_uchar *)cd->start_workspace + this_offset; } for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len); cd->hwm += LINK_SIZE; } save_hwm = this_hwm; code += len; } } } if (repeat_max > 0) repeat_max -= repeat_min; } /* This code is common to both the zero and non-zero minimum cases. If the maximum is limited, it replicates the group in a nested fashion, remembering the bracket starts on a stack. In the case of a zero minimum, the first one was set up above. In all cases the repeat_max now specifies the number of additional copies needed. Again, we must remember to replicate entries on the forward reference list. */ if (repeat_max >= 0) { /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. For each repetition we must add 1 to the length for BRAZERO and for all but the last repetition we must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is a 64-bit integer type when available, otherwise double. */ if (lengthptr != NULL && repeat_max > 0) { int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) - 2 - 2*LINK_SIZE; /* Last one doesn't nest */ if ((INT64_OR_DOUBLE)repeat_max * (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE) > (INT64_OR_DOUBLE)INT_MAX || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += delta; } /* This is compiling for real */ else for (i = repeat_max - 1; i >= 0; i--) { pcre_uchar *hc; pcre_uchar *this_hwm = cd->hwm; *code++ = OP_BRAZERO + repeat_type; /* All but the final copy start a new nesting, maintaining the chain of brackets outstanding. */ if (i != 0) { int offset; *code++ = OP_BRA; offset = (bralink == NULL)? 0 : (int)(code - bralink); bralink = code; PUTINC(code, 0, offset); } memcpy(code, previous, IN_UCHARS(len)); /* Ensure there is enough workspace for forward references before copying them. */ while (cd->hwm > cd->start_workspace + cd->workspace_size - WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm)) { int save_offset = save_hwm - cd->start_workspace; int this_offset = this_hwm - cd->start_workspace; *errorcodeptr = expand_workspace(cd); if (*errorcodeptr != 0) goto FAILED; save_hwm = (pcre_uchar *)cd->start_workspace + save_offset; this_hwm = (pcre_uchar *)cd->start_workspace + this_offset; } for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1)); cd->hwm += LINK_SIZE; } save_hwm = this_hwm; code += len; } /* Now chain through the pending brackets, and fill in their length fields (which are holding the chain links pro tem). */ while (bralink != NULL) { int oldlinkoffset; int offset = (int)(code - bralink + 1); pcre_uchar *bra = code - offset; oldlinkoffset = GET(bra, 1); bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; *code++ = OP_KET; PUTINC(code, 0, offset); PUT(bra, 1, offset); } } /* If the maximum is unlimited, set a repeater in the final copy. For ONCE brackets, that's all we need to do. However, possessively repeated ONCE brackets can be converted into non-capturing brackets, as the behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to deal with possessive ONCEs specially. Otherwise, when we are doing the actual compile phase, check to see whether this group is one that could match an empty string. If so, convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so that runtime checking can be done. [This check is also applied to ONCE groups at runtime, but in a different way.] Then, if the quantifier was possessive and the bracket is not a conditional, we convert the BRA code to the POS form, and the KET code to KETRPOS. (It turns out to be convenient at runtime to detect this kind of subpattern at both the start and at the end.) The use of special opcodes makes it possible to reduce greatly the stack usage in pcre_exec(). If the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. Then, if the minimum number of matches is 1 or 0, cancel the possessive flag so that the default action below, of wrapping everything inside atomic brackets, does not happen. When the minimum is greater than 1, there will be earlier copies of the group, and so we still have to wrap the whole thing. */ else { pcre_uchar *ketcode = code - 1 - LINK_SIZE; pcre_uchar *bracode = ketcode - GET(ketcode, 1); /* Convert possessive ONCE brackets to non-capturing */ if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) && possessive_quantifier) *bracode = OP_BRA; /* For non-possessive ONCE brackets, all we need to do is to set the KET. */ if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC) *ketcode = OP_KETRMAX + repeat_type; /* Handle non-ONCE brackets and possessive ONCEs (which have been converted to non-capturing above). */ else { /* In the compile phase, check for empty string matching. */ if (lengthptr == NULL) { pcre_uchar *scode = bracode; do { if (could_be_empty_branch(scode, ketcode, utf, cd)) { *bracode += OP_SBRA - OP_BRA; break; } scode += GET(scode, 1); } while (*scode == OP_ALT); } /* Handle possessive quantifiers. */ if (possessive_quantifier) { /* For COND brackets, we wrap the whole thing in a possessively repeated non-capturing bracket, because we have not invented POS versions of the COND opcodes. Because we are moving code along, we must ensure that any pending recursive references are updated. */ if (*bracode == OP_COND || *bracode == OP_SCOND) { int nlen = (int)(code - bracode); *code = OP_END; adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm); memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen)); code += 1 + LINK_SIZE; nlen += 1 + LINK_SIZE; *bracode = OP_BRAPOS; *code++ = OP_KETRPOS; PUTINC(code, 0, nlen); PUT(bracode, 1, nlen); } /* For non-COND brackets, we modify the BRA code and use KETRPOS. */ else { *bracode += 1; /* Switch to xxxPOS opcodes */ *ketcode = OP_KETRPOS; } /* If the minimum is zero, mark it as possessive, then unset the possessive flag when the minimum is 0 or 1. */ if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO; if (repeat_min < 2) possessive_quantifier = FALSE; } /* Non-possessive quantifier */ else *ketcode = OP_KETRMAX + repeat_type; } } } /* If previous is OP_FAIL, it was generated by an empty class [] in JavaScript mode. The other ways in which OP_FAIL can be generated, that is by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat" error above. We can just ignore the repeat in JS case. */ else if (*previous == OP_FAIL) goto END_REPEAT; /* Else there's some kind of shambles */ else { *errorcodeptr = ERR11; goto FAILED; } /* If the character following a repeat is '+', or if certain optimization tests above succeeded, possessive_quantifier is TRUE. For some opcodes, there are special alternative opcodes for this case. For anything else, we wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+' notation is just syntactic sugar, taken from Sun's Java package, but the special opcodes can optimize it. Some (but not all) possessively repeated subpatterns have already been completely handled in the code just above. For them, possessive_quantifier is always FALSE at this stage. Note that the repeated item starts at tempcode, not at previous, which might be the first part of a string whose (former) last char we repeated. Possessifying an 'exact' quantifier has no effect, so we can ignore it. But an 'upto' may follow. We skip over an 'exact' item, and then test the length of what remains before proceeding. */ if (possessive_quantifier) { int len; if (*tempcode == OP_TYPEEXACT) tempcode += PRIV(OP_lengths)[*tempcode] + ((tempcode[1 + IMM2_SIZE] == OP_PROP || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT) { tempcode += PRIV(OP_lengths)[*tempcode]; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(tempcode[-1])) tempcode += GET_EXTRALEN(tempcode[-1]); #endif } len = (int)(code - tempcode); if (len > 0) switch (*tempcode) { case OP_STAR: *tempcode = OP_POSSTAR; break; case OP_PLUS: *tempcode = OP_POSPLUS; break; case OP_QUERY: *tempcode = OP_POSQUERY; break; case OP_UPTO: *tempcode = OP_POSUPTO; break; case OP_STARI: *tempcode = OP_POSSTARI; break; case OP_PLUSI: *tempcode = OP_POSPLUSI; break; case OP_QUERYI: *tempcode = OP_POSQUERYI; break; case OP_UPTOI: *tempcode = OP_POSUPTOI; break; case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break; case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break; case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break; case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break; case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break; case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break; case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break; case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break; case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break; case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break; case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break; case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break; /* Because we are moving code along, we must ensure that any pending recursive references are updated. */ default: *code = OP_END; adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm); memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len)); code += 1 + LINK_SIZE; len += 1 + LINK_SIZE; tempcode[0] = OP_ONCE; *code++ = OP_KET; PUTINC(code, 0, len); PUT(tempcode, 1, len); break; } } /* In all case we no longer have a previous item. We also set the "follows varying string" flag for subsequently encountered reqchars if it isn't already set and we have just passed a varying length item. */ END_REPEAT: previous = NULL; cd->req_varyopt |= reqvary; break; /* ===================================================================*/ /* Start of nested parenthesized sub-expression, or comment or lookahead or lookbehind or option setting or condition or all the other extended parenthesis forms. */ case CHAR_LEFT_PARENTHESIS: newoptions = options; skipbytes = 0; bravalue = OP_CBRA; save_hwm = cd->hwm; reset_bracount = FALSE; /* First deal with various "verbs" that can be introduced by '*'. */ ptr++; if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':' || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0)))) { int i, namelen; int arglen = 0; const char *vn = verbnames; const pcre_uchar *name = ptr + 1; const pcre_uchar *arg = NULL; previous = NULL; ptr++; while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++; namelen = (int)(ptr - name); /* It appears that Perl allows any characters whatsoever, other than a closing parenthesis, to appear in arguments, so we no longer insist on letters, digits, and underscores. */ if (*ptr == CHAR_COLON) { arg = ++ptr; while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; arglen = (int)(ptr - arg); if (arglen > (int)MAX_MARK) { *errorcodeptr = ERR75; goto FAILED; } } if (*ptr != CHAR_RIGHT_PARENTHESIS) { *errorcodeptr = ERR60; goto FAILED; } /* Scan the table of verb names */ for (i = 0; i < verbcount; i++) { if (namelen == verbs[i].len && STRNCMP_UC_C8(name, vn, namelen) == 0) { /* Check for open captures before ACCEPT and convert it to ASSERT_ACCEPT if in an assertion. */ if (verbs[i].op == OP_ACCEPT) { open_capitem *oc; if (arglen != 0) { *errorcodeptr = ERR59; goto FAILED; } cd->had_accept = TRUE; for (oc = cd->open_caps; oc != NULL; oc = oc->next) { *code++ = OP_CLOSE; PUT2INC(code, 0, oc->number); } *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; /* Do not set firstchar after *ACCEPT */ if (firstchar == REQ_UNSET) firstchar = REQ_NONE; } /* Handle other cases with/without an argument */ else if (arglen == 0) { if (verbs[i].op < 0) /* Argument is mandatory */ { *errorcodeptr = ERR66; goto FAILED; } *code = verbs[i].op; if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN; } else { if (verbs[i].op_arg < 0) /* Argument is forbidden */ { *errorcodeptr = ERR59; goto FAILED; } *code = verbs[i].op_arg; if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN; *code++ = arglen; memcpy(code, arg, IN_UCHARS(arglen)); code += arglen; *code++ = 0; } break; /* Found verb, exit loop */ } vn += verbs[i].len + 1; } if (i < verbcount) continue; /* Successfully handled a verb */ *errorcodeptr = ERR60; /* Verb not recognized */ goto FAILED; } /* Deal with the extended parentheses; all are introduced by '?', and the appearance of any of them means that this is not a capturing group. */ else if (*ptr == CHAR_QUESTION_MARK) { int i, set, unset, namelen; int *optset; const pcre_uchar *name; pcre_uchar *slot; switch (*(++ptr)) { case CHAR_NUMBER_SIGN: /* Comment; skip to ket */ ptr++; while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; if (*ptr == 0) { *errorcodeptr = ERR18; goto FAILED; } continue; /* ------------------------------------------------------------ */ case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ reset_bracount = TRUE; /* Fall through */ /* ------------------------------------------------------------ */ case CHAR_COLON: /* Non-capturing bracket */ bravalue = OP_BRA; ptr++; break; /* ------------------------------------------------------------ */ case CHAR_LEFT_PARENTHESIS: bravalue = OP_COND; /* Conditional group */ /* A condition can be an assertion, a number (referring to a numbered group), a name (referring to a named group), or 'R', referring to recursion. R and R&name are also permitted for recursion tests. There are several syntaxes for testing a named group: (?(name)) is used by Python; Perl 5.10 onwards uses (?() or (?('name')). There are two unfortunate ambiguities, caused by history. (a) 'R' can be the recursive thing or the name 'R' (and similarly for 'R' followed by digits), 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. */ /* For conditions that are assertions, check the syntax, and then exit the switch. This will take control down to where bracketed groups, including assertions, are processed. */ if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN || ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN)) break; /* Most other conditions use OP_CREF (a couple change to OP_RREF below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */ code[1+LINK_SIZE] = OP_CREF; skipbytes = 1+IMM2_SIZE; refsign = -1; /* Check for a test for recursion in a named group. */ if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND) { terminator = -1; ptr += 2; code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */ } /* Check for a test for a named group's having been set, using the Perl syntax (?() or (?('name') */ else if (ptr[1] == CHAR_LESS_THAN_SIGN) { terminator = CHAR_GREATER_THAN_SIGN; ptr++; } else if (ptr[1] == CHAR_APOSTROPHE) { terminator = CHAR_APOSTROPHE; ptr++; } else { terminator = 0; if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr); } /* We now expect to read a name; any thing else is an error */ if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0) { ptr += 1; /* To get the right offset */ *errorcodeptr = ERR28; goto FAILED; } /* Read the name, but also get it as a number if it's all digits */ recno = 0; name = ++ptr; while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) { if (recno >= 0) recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1; ptr++; } namelen = (int)(ptr - name); if ((terminator > 0 && *ptr++ != terminator) || *ptr++ != CHAR_RIGHT_PARENTHESIS) { ptr--; /* Error offset */ *errorcodeptr = ERR26; goto FAILED; } /* Do no further checking in the pre-compile phase. */ if (lengthptr != NULL) break; /* In the real compile we do the work of looking for the actual reference. If the string started with "+" or "-" we require the rest to be digits, in which case recno will be set. */ if (refsign > 0) { if (recno <= 0) { *errorcodeptr = ERR58; goto FAILED; } recno = (refsign == CHAR_MINUS)? cd->bracount - recno + 1 : recno +cd->bracount; if (recno <= 0 || recno > cd->final_bracount) { *errorcodeptr = ERR15; goto FAILED; } PUT2(code, 2+LINK_SIZE, recno); break; } /* Otherwise (did not start with "+" or "-"), start by looking for the name. If we find a name, add one to the opcode to change OP_CREF or OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same, except they record that the reference was originally to a name. The information is used to check duplicate names. */ slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break; slot += cd->name_entry_size; } /* Found a previous named subpattern */ if (i < cd->names_found) { recno = GET2(slot, 0); PUT2(code, 2+LINK_SIZE, recno); code[1+LINK_SIZE]++; } /* Search the pattern for a forward reference */ else if ((i = find_parens(cd, name, namelen, (options & PCRE_EXTENDED) != 0, utf)) > 0) { PUT2(code, 2+LINK_SIZE, i); code[1+LINK_SIZE]++; } /* If terminator == 0 it means that the name followed directly after the opening parenthesis [e.g. (?(abc)...] and in this case there are some further alternatives to try. For the cases where terminator != 0 [things like (?(... or (?('name')... or (?(R&name)... ] we have now checked all the possibilities, so give an error. */ else if (terminator != 0) { *errorcodeptr = ERR15; goto FAILED; } /* Check for (?(R) for recursion. Allow digits after R to specify a specific group number. */ else if (*name == CHAR_R) { recno = 0; for (i = 1; i < namelen; i++) { if (!IS_DIGIT(name[i])) { *errorcodeptr = ERR15; goto FAILED; } recno = recno * 10 + name[i] - CHAR_0; } if (recno == 0) recno = RREF_ANY; code[1+LINK_SIZE] = OP_RREF; /* Change test type */ PUT2(code, 2+LINK_SIZE, recno); } /* Similarly, check for the (?(DEFINE) "condition", which is always false. */ else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0) { code[1+LINK_SIZE] = OP_DEF; skipbytes = 1; } /* Check for the "name" actually being a subpattern number. We are in the second pass here, so final_bracount is set. */ else if (recno > 0 && recno <= cd->final_bracount) { PUT2(code, 2+LINK_SIZE, recno); } /* Either an unidentified subpattern, or a reference to (?(0) */ else { *errorcodeptr = (recno == 0)? ERR35: ERR15; goto FAILED; } break; /* ------------------------------------------------------------ */ case CHAR_EQUALS_SIGN: /* Positive lookahead */ bravalue = OP_ASSERT; cd->assert_depth += 1; ptr++; break; /* ------------------------------------------------------------ */ case CHAR_EXCLAMATION_MARK: /* Negative lookahead */ ptr++; if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */ { *code++ = OP_FAIL; previous = NULL; continue; } bravalue = OP_ASSERT_NOT; cd->assert_depth += 1; break; /* ------------------------------------------------------------ */ case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */ switch (ptr[1]) { case CHAR_EQUALS_SIGN: /* Positive lookbehind */ bravalue = OP_ASSERTBACK; cd->assert_depth += 1; ptr += 2; break; case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */ bravalue = OP_ASSERTBACK_NOT; cd->assert_depth += 1; ptr += 2; break; default: /* Could be name define, else bad */ if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0) goto DEFINE_NAME; ptr++; /* Correct offset for error */ *errorcodeptr = ERR24; goto FAILED; } break; /* ------------------------------------------------------------ */ case CHAR_GREATER_THAN_SIGN: /* One-time brackets */ bravalue = OP_ONCE; ptr++; break; /* ------------------------------------------------------------ */ case CHAR_C: /* Callout - may be followed by digits; */ previous_callout = code; /* Save for later completion */ after_manual_callout = 1; /* Skip one item before completing */ *code++ = OP_CALLOUT; { int n = 0; ptr++; while(IS_DIGIT(*ptr)) n = n * 10 + *ptr++ - CHAR_0; if (*ptr != CHAR_RIGHT_PARENTHESIS) { *errorcodeptr = ERR39; goto FAILED; } if (n > 255) { *errorcodeptr = ERR38; goto FAILED; } *code++ = n; PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ code += 2 * LINK_SIZE; } previous = NULL; continue; /* ------------------------------------------------------------ */ case CHAR_P: /* Python-style named subpattern handling */ if (*(++ptr) == CHAR_EQUALS_SIGN || *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */ { is_recurse = *ptr == CHAR_GREATER_THAN_SIGN; terminator = CHAR_RIGHT_PARENTHESIS; goto NAMED_REF_OR_RECURSE; } else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */ { *errorcodeptr = ERR41; goto FAILED; } /* Fall through to handle (?P< as (?< is handled */ /* ------------------------------------------------------------ */ DEFINE_NAME: /* Come here from (?< handling */ case CHAR_APOSTROPHE: { terminator = (*ptr == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; name = ++ptr; while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = (int)(ptr - name); /* In the pre-compile phase, just do a syntax check. */ if (lengthptr != NULL) { if (*ptr != terminator) { *errorcodeptr = ERR42; goto FAILED; } if (cd->names_found >= MAX_NAME_COUNT) { *errorcodeptr = ERR49; goto FAILED; } if (namelen + IMM2_SIZE + 1 > cd->name_entry_size) { cd->name_entry_size = namelen + IMM2_SIZE + 1; if (namelen > MAX_NAME_SIZE) { *errorcodeptr = ERR48; goto FAILED; } } } /* In the real compile, create the entry in the table, maintaining alphabetical order. Duplicate names for different numbers are permitted only if PCRE_DUPNAMES is set. Duplicate names for the same number are always OK. (An existing number can be re-used if (?| appears in the pattern.) In either event, a duplicate name results in a duplicate entry in the table, even if the number is the same. This is because the number of names, and hence the table size, is computed in the pre-compile, and it affects various numbers and pointers which would all have to be modified, and the compiled code moved down, if duplicates with the same number were omitted from the table. This doesn't seem worth the hassle. However, *different* names for the same number are not permitted. */ else { BOOL dupname = FALSE; slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen)); if (crc == 0) { if (slot[IMM2_SIZE+namelen] == 0) { if (GET2(slot, 0) != cd->bracount + 1 && (options & PCRE_DUPNAMES) == 0) { *errorcodeptr = ERR43; goto FAILED; } else dupname = TRUE; } else crc = -1; /* Current name is a substring */ } /* Make space in the table and break the loop for an earlier name. For a duplicate or later name, carry on. We do this for duplicates so that in the simple case (when ?(| is not used) they are in order of their numbers. */ if (crc < 0) { memmove(slot + cd->name_entry_size, slot, IN_UCHARS((cd->names_found - i) * cd->name_entry_size)); break; } /* Continue the loop for a later or duplicate name */ slot += cd->name_entry_size; } /* For non-duplicate names, check for a duplicate number before adding the new name. */ if (!dupname) { pcre_uchar *cslot = cd->name_table; for (i = 0; i < cd->names_found; i++) { if (cslot != slot) { if (GET2(cslot, 0) == cd->bracount + 1) { *errorcodeptr = ERR65; goto FAILED; } } else i--; cslot += cd->name_entry_size; } } PUT2(slot, 0, cd->bracount + 1); memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen)); slot[IMM2_SIZE + namelen] = 0; } } /* In both pre-compile and compile, count the number of names we've encountered. */ cd->names_found++; ptr++; /* Move past > or ' */ goto NUMBERED_GROUP; /* ------------------------------------------------------------ */ case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */ terminator = CHAR_RIGHT_PARENTHESIS; is_recurse = TRUE; /* Fall through */ /* We come here from the Python syntax above that handles both references (?P=name) and recursion (?P>name), as well as falling through from the Perl recursion syntax (?&name). We also come here from the Perl \k or \k'name' back reference syntax and the \k{name} .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */ NAMED_REF_OR_RECURSE: name = ++ptr; while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = (int)(ptr - name); /* In the pre-compile phase, do a syntax check. We used to just set a dummy reference number, because it was not used in the first pass. However, with the change of recursive back references to be atomic, we have to look for the number so that this state can be identified, as otherwise the incorrect length is computed. If it's not a backwards reference, the dummy number will do. */ if (lengthptr != NULL) { const pcre_uchar *temp; if (namelen == 0) { *errorcodeptr = ERR62; goto FAILED; } if (*ptr != terminator) { *errorcodeptr = ERR42; goto FAILED; } if (namelen > MAX_NAME_SIZE) { *errorcodeptr = ERR48; goto FAILED; } /* The name table does not exist in the first pass, so we cannot do a simple search as in the code below. Instead, we have to scan the pattern to find the number. It is important that we scan it only as far as we have got because the syntax of named subpatterns has not been checked for the rest of the pattern, and find_parens() assumes correct syntax. In any case, it's a waste of resources to scan further. We stop the scan at the current point by temporarily adjusting the value of cd->endpattern. */ temp = cd->end_pattern; cd->end_pattern = ptr; recno = find_parens(cd, name, namelen, (options & PCRE_EXTENDED) != 0, utf); cd->end_pattern = temp; if (recno < 0) recno = 0; /* Forward ref; set dummy number */ } /* In the real compile, seek the name in the table. We check the name first, and then check that we have reached the end of the name in the table. That way, if the name that is longer than any in the table, the comparison will fail without reading beyond the table entry. */ else { slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 && slot[IMM2_SIZE+namelen] == 0) break; slot += cd->name_entry_size; } if (i < cd->names_found) /* Back reference */ { recno = GET2(slot, 0); } else if ((recno = /* Forward back reference */ find_parens(cd, name, namelen, (options & PCRE_EXTENDED) != 0, utf)) <= 0) { *errorcodeptr = ERR15; goto FAILED; } } /* In both phases, we can now go to the code than handles numerical recursion or backreferences. */ if (is_recurse) goto HANDLE_RECURSION; else goto HANDLE_REFERENCE; /* ------------------------------------------------------------ */ case CHAR_R: /* Recursion */ ptr++; /* Same as (?0) */ /* Fall through */ /* ------------------------------------------------------------ */ case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */ case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: { const pcre_uchar *called; terminator = CHAR_RIGHT_PARENTHESIS; /* Come here from the \g<...> and \g'...' code (Oniguruma compatibility). However, the syntax has been checked to ensure that the ... are a (signed) number, so that neither ERR63 nor ERR29 will be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY ever be taken. */ HANDLE_NUMERICAL_RECURSION: if ((refsign = *ptr) == CHAR_PLUS) { ptr++; if (!IS_DIGIT(*ptr)) { *errorcodeptr = ERR63; goto FAILED; } } else if (refsign == CHAR_MINUS) { if (!IS_DIGIT(ptr[1])) goto OTHER_CHAR_AFTER_QUERY; ptr++; } recno = 0; while(IS_DIGIT(*ptr)) recno = recno * 10 + *ptr++ - CHAR_0; if (*ptr != terminator) { *errorcodeptr = ERR29; goto FAILED; } if (refsign == CHAR_MINUS) { if (recno == 0) { *errorcodeptr = ERR58; goto FAILED; } recno = cd->bracount - recno + 1; if (recno <= 0) { *errorcodeptr = ERR15; goto FAILED; } } else if (refsign == CHAR_PLUS) { if (recno == 0) { *errorcodeptr = ERR58; goto FAILED; } recno += cd->bracount; } /* Come here from code above that handles a named recursion */ HANDLE_RECURSION: previous = code; called = cd->start_code; /* When we are actually compiling, find the bracket that is being referenced. Temporarily end the regex in case it doesn't exist before this point. If we end up with a forward reference, first check that the bracket does occur later so we can give the error (and position) now. Then remember this forward reference in the workspace so it can be filled in at the end. */ if (lengthptr == NULL) { *code = OP_END; if (recno != 0) called = PRIV(find_bracket)(cd->start_code, utf, recno); /* Forward reference */ if (called == NULL) { if (find_parens(cd, NULL, recno, (options & PCRE_EXTENDED) != 0, utf) < 0) { *errorcodeptr = ERR15; goto FAILED; } /* Fudge the value of "called" so that when it is inserted as an offset below, what it actually inserted is the reference number of the group. Then remember the forward reference. */ called = cd->start_code + recno; if (cd->hwm >= cd->start_workspace + cd->workspace_size - WORK_SIZE_SAFETY_MARGIN) { *errorcodeptr = expand_workspace(cd); if (*errorcodeptr != 0) goto FAILED; } PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code)); } /* If not a forward reference, and the subpattern is still open, this is a recursive call. We check to see if this is a left recursion that could loop for ever, and diagnose that case. We must not, however, do this check if we are in a conditional subpattern because the condition might be testing for recursion in a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid. Forever loops are also detected at runtime, so those that occur in conditional subpatterns will be picked up then. */ else if (GET(called, 1) == 0 && cond_depth <= 0 && could_be_empty(called, code, bcptr, utf, cd)) { *errorcodeptr = ERR40; goto FAILED; } } /* Insert the recursion/subroutine item. It does not have a set first character (relevant if it is repeated, because it will then be wrapped with ONCE brackets). */ *code = OP_RECURSE; PUT(code, 1, (int)(called - cd->start_code)); code += 1 + LINK_SIZE; groupsetfirstchar = FALSE; } /* Can't determine a first byte now */ if (firstchar == REQ_UNSET) firstchar = REQ_NONE; continue; /* ------------------------------------------------------------ */ default: /* Other characters: check option setting */ OTHER_CHAR_AFTER_QUERY: set = unset = 0; optset = &set; while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON) { switch (*ptr++) { case CHAR_MINUS: optset = &unset; break; case CHAR_J: /* Record that it changed in the external options */ *optset |= PCRE_DUPNAMES; cd->external_flags |= PCRE_JCHANGED; break; case CHAR_i: *optset |= PCRE_CASELESS; break; case CHAR_m: *optset |= PCRE_MULTILINE; break; case CHAR_s: *optset |= PCRE_DOTALL; break; case CHAR_x: *optset |= PCRE_EXTENDED; break; case CHAR_U: *optset |= PCRE_UNGREEDY; break; case CHAR_X: *optset |= PCRE_EXTRA; break; default: *errorcodeptr = ERR12; ptr--; /* Correct the offset */ goto FAILED; } } /* Set up the changed option bits, but don't change anything yet. */ newoptions = (options | set) & (~unset); /* If the options ended with ')' this is not the start of a nested group with option changes, so the options change at this level. If this item is right at the start of the pattern, the options can be abstracted and made external in the pre-compile phase, and ignored in the compile phase. This can be helpful when matching -- for instance in caseless checking of required bytes. If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are definitely *not* at the start of the pattern because something has been compiled. In the pre-compile phase, however, the code pointer can have that value after the start, because it gets reset as code is discarded during the pre-compile. However, this can happen only at top level - if we are within parentheses, the starting BRA will still be present. At any parenthesis level, the length value can be used to test if anything has been compiled at that level. Thus, a test for both these conditions is necessary to ensure we correctly detect the start of the pattern in both phases. If we are not at the pattern start, reset the greedy defaults and the case value for firstchar and reqchar. */ if (*ptr == CHAR_RIGHT_PARENTHESIS) { if (code == cd->start_code + 1 + LINK_SIZE && (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE)) { cd->external_options = newoptions; } else { greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; } /* Change options at this level, and pass them back for use in subsequent branches. */ *optionsptr = options = newoptions; previous = NULL; /* This item can't be repeated */ continue; /* It is complete */ } /* If the options ended with ':' we are heading into a nested group with possible change of options. Such groups are non-capturing and are not assertions of any kind. All we need to do is skip over the ':'; the newoptions value is handled below. */ bravalue = OP_BRA; ptr++; } /* End of switch for character following (? */ } /* End of (? handling */ /* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE is set, all unadorned brackets become non-capturing and behave like (?:...) brackets. */ else if ((options & PCRE_NO_AUTO_CAPTURE) != 0) { bravalue = OP_BRA; } /* Else we have a capturing group. */ else { NUMBERED_GROUP: cd->bracount += 1; PUT2(code, 1+LINK_SIZE, cd->bracount); skipbytes = IMM2_SIZE; } /* Process nested bracketed regex. Assertions used not to be repeatable, but this was changed for Perl compatibility, so all kinds can now be repeated. We copy code into a non-register variable (tempcode) in order to be able to pass its address because some compilers complain otherwise. */ previous = code; /* For handling repetition */ *code = bravalue; tempcode = code; tempreqvary = cd->req_varyopt; /* Save value before bracket */ tempbracount = cd->bracount; /* Save value before bracket */ length_prevgroup = 0; /* Initialize for pre-compile phase */ if (!compile_regex( newoptions, /* The complete new option state */ &tempcode, /* Where to put code (updated) */ &ptr, /* Input pointer (updated) */ errorcodeptr, /* Where to put an error message */ (bravalue == OP_ASSERTBACK || bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ reset_bracount, /* True if (?| group */ skipbytes, /* Skip over bracket number */ cond_depth + ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */ &subfirstchar, /* For possible first char */ &subreqchar, /* For possible last char */ bcptr, /* Current branch chain */ cd, /* Tables block */ (lengthptr == NULL)? NULL : /* Actual compile phase */ &length_prevgroup /* Pre-compile phase */ )) goto FAILED; /* If this was an atomic group and there are no capturing groups within it, generate OP_ONCE_NC instead of OP_ONCE. */ if (bravalue == OP_ONCE && cd->bracount <= tempbracount) *code = OP_ONCE_NC; if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT) cd->assert_depth -= 1; /* At the end of compiling, code is still pointing to the start of the group, while tempcode has been updated to point past the end of the group. The pattern pointer (ptr) is on the bracket. If this is a conditional bracket, check that there are no more than two branches in the group, or just one if it's a DEFINE group. We do this in the real compile phase, not in the pre-pass, where the whole group may not be available. */ if (bravalue == OP_COND && lengthptr == NULL) { pcre_uchar *tc = code; int condcount = 0; do { condcount++; tc += GET(tc,1); } while (*tc != OP_KET); /* A DEFINE group is never obeyed inline (the "condition" is always false). It must have only one branch. */ if (code[LINK_SIZE+1] == OP_DEF) { if (condcount > 1) { *errorcodeptr = ERR54; goto FAILED; } bravalue = OP_DEF; /* Just a flag to suppress char handling below */ } /* A "normal" conditional group. If there is just one branch, we must not make use of its firstchar or reqchar, because this is equivalent to an empty second branch. */ else { if (condcount > 2) { *errorcodeptr = ERR27; goto FAILED; } if (condcount == 1) subfirstchar = subreqchar = REQ_NONE; } } /* Error if hit end of pattern */ if (*ptr != CHAR_RIGHT_PARENTHESIS) { *errorcodeptr = ERR14; goto FAILED; } /* In the pre-compile phase, update the length by the length of the group, less the brackets at either end. Then reduce the compiled code to just a set of non-capturing brackets so that it doesn't use much memory if it is duplicated by a quantifier.*/ if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE; code++; /* This already contains bravalue */ PUTINC(code, 0, 1 + LINK_SIZE); *code++ = OP_KET; PUTINC(code, 0, 1 + LINK_SIZE); break; /* No need to waste time with special character handling */ } /* Otherwise update the main code pointer to the end of the group. */ code = tempcode; /* For a DEFINE group, required and first character settings are not relevant. */ if (bravalue == OP_DEF) break; /* Handle updating of the required and first characters for other types of group. Update for normal brackets of all kinds, and conditions with two branches (see code above). If the bracket is followed by a quantifier with zero repeat, we have to back off. Hence the definition of zeroreqchar and zerofirstchar outside the main loop so that they can be accessed for the back off. */ zeroreqchar = reqchar; zerofirstchar = firstchar; groupsetfirstchar = FALSE; if (bravalue >= OP_ONCE) { /* If we have not yet set a firstchar in this branch, take it from the subpattern, remembering that it was set here so that a repeat of more than one can replicate it as reqchar if necessary. If the subpattern has no firstchar, set "none" for the whole branch. In both cases, a zero repeat forces firstchar to "none". */ if (firstchar == REQ_UNSET) { if (subfirstchar >= 0) { firstchar = subfirstchar; groupsetfirstchar = TRUE; } else firstchar = REQ_NONE; zerofirstchar = REQ_NONE; } /* If firstchar was previously set, convert the subpattern's firstchar into reqchar if there wasn't one, using the vary flag that was in existence beforehand. */ else if (subfirstchar >= 0 && subreqchar < 0) subreqchar = subfirstchar | tempreqvary; /* If the subpattern set a required byte (or set a first byte that isn't really the first byte - see above), set it. */ if (subreqchar >= 0) reqchar = subreqchar; } /* For a forward assertion, we take the reqchar, if set. This can be helpful if the pattern that follows the assertion doesn't set a different char. For example, it's useful for /(?=abcde).+/. We can't set firstchar for an assertion, however because it leads to incorrect effect for patterns such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead of a firstchar. This is overcome by a scan at the end if there's no firstchar, looking for an asserted first char. */ else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar; break; /* End of processing '(' */ /* ===================================================================*/ /* Handle metasequences introduced by \. For ones like \d, the ESC_ values are arranged to be the negation of the corresponding OP_values in the default case when PCRE_UCP is not set. For the back references, the values are ESC_REF plus the reference number. Only back references and those types that consume a character may be repeated. We can test for values between ESC_b and ESC_Z for the latter; this may have to change if any new ones are ever created. */ case CHAR_BACKSLASH: tempptr = ptr; c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE); if (*errorcodeptr != 0) goto FAILED; if (c < 0) { if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) ptr += 2; /* avoid empty string */ else inescq = TRUE; continue; } if (-c == ESC_E) continue; /* Perl ignores an orphan \E */ /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z) firstchar = REQ_NONE; /* Set values to reset to if this is followed by a zero repeat. */ zerofirstchar = firstchar; zeroreqchar = reqchar; /* \g or \g'name' is a subroutine call by name and \g or \g'n' is a subroutine call by number (Oniguruma syntax). In fact, the value -ESC_g is returned only for these cases. So we don't need to check for < or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as that is a synonym for a named back reference). */ if (-c == ESC_g) { const pcre_uchar *p; save_hwm = cd->hwm; /* Normally this is set when '(' is read */ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; /* These two statements stop the compiler for warning about possibly unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In fact, because we actually check for a number below, the paths that would actually be in error are never taken. */ skipbytes = 0; reset_bracount = FALSE; /* Test for a name */ if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS) { BOOL is_a_number = TRUE; for (p = ptr + 1; *p != 0 && *p != terminator; p++) { if (!MAX_255(*p)) { is_a_number = FALSE; break; } if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE; if ((cd->ctypes[*p] & ctype_word) == 0) break; } if (*p != terminator) { *errorcodeptr = ERR57; break; } if (is_a_number) { ptr++; goto HANDLE_NUMERICAL_RECURSION; } is_recurse = TRUE; goto NAMED_REF_OR_RECURSE; } /* Test a signed number in angle brackets or quotes. */ p = ptr + 2; while (IS_DIGIT(*p)) p++; if (*p != terminator) { *errorcodeptr = ERR57; break; } ptr++; goto HANDLE_NUMERICAL_RECURSION; } /* \k or \k'name' is a back reference by name (Perl syntax). We also support \k{name} (.NET syntax). */ if (-c == ESC_k) { if ((ptr[1] != CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET)) { *errorcodeptr = ERR69; break; } is_recurse = FALSE; terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)? CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET; goto NAMED_REF_OR_RECURSE; } /* Back references are handled specially; must disable firstchar if not set to cope with cases like (?=(\w+))\1: which would otherwise set ':' later. */ if (-c >= ESC_REF) { open_capitem *oc; recno = -c - ESC_REF; HANDLE_REFERENCE: /* Come here from named backref handling */ if (firstchar == REQ_UNSET) firstchar = REQ_NONE; previous = code; *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF; PUT2INC(code, 0, recno); cd->backref_map |= (recno < 32)? (1 << recno) : 1; if (recno > cd->top_backref) cd->top_backref = recno; /* Check to see if this back reference is recursive, that it, it is inside the group that it references. A flag is set so that the group can be made atomic. */ for (oc = cd->open_caps; oc != NULL; oc = oc->next) { if (oc->number == recno) { oc->flag = TRUE; break; } } } /* So are Unicode property matches, if supported. */ #ifdef SUPPORT_UCP else if (-c == ESC_P || -c == ESC_p) { BOOL negated; int pdata; int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); if (ptype < 0) goto FAILED; previous = code; *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP; *code++ = ptype; *code++ = pdata; } #else /* If Unicode properties are not supported, \X, \P, and \p are not allowed. */ else if (-c == ESC_X || -c == ESC_P || -c == ESC_p) { *errorcodeptr = ERR45; goto FAILED; } #endif /* For the rest (including \X when Unicode properties are supported), we can obtain the OP value by negating the escape value in the default situation when PCRE_UCP is not set. When it *is* set, we substitute Unicode property tests. Note that \b and \B do a one-character lookbehind. */ else { if ((-c == ESC_b || -c == ESC_B) && cd->max_lookbehind == 0) cd->max_lookbehind = 1; #ifdef SUPPORT_UCP if (-c >= ESC_DU && -c <= ESC_wu) { nestptr = ptr + 1; /* Where to resume */ ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */ } else #endif /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. */ { previous = (-c > ESC_b && -c < ESC_Z)? code : NULL; *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c; } } continue; } /* We have a data character whose value is in c. In UTF-8 mode it may have a value > 127. We set its representation in the length/buffer, and then handle it as a data character. */ #ifdef SUPPORT_UTF if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) mclength = PRIV(ord2utf)(c, mcbuffer); else #endif { mcbuffer[0] = c; mclength = 1; } goto ONE_CHAR; /* ===================================================================*/ /* Handle a literal character. It is guaranteed not to be whitespace or # when the extended flag is set. If we are in UTF-8 mode, it may be a multi-byte literal character. */ default: NORMAL_CHAR: mclength = 1; mcbuffer[0] = c; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(c)) ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr)); #endif /* At this point we have the character's bytes in mcbuffer, and the length in mclength. When not in UTF-8 mode, the length is always 1. */ ONE_CHAR: previous = code; *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR; for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; /* Remember if \r or \n were seen */ if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; /* Set the first and required bytes appropriately. If no previous first byte, set it from this character, but revert to none on a zero repeat. Otherwise, leave the firstchar value alone, and don't change it on a zero repeat. */ if (firstchar == REQ_UNSET) { zerofirstchar = REQ_NONE; zeroreqchar = reqchar; /* If the character is more than one byte long, we can set firstchar only if it is not to be matched caselessly. */ if (mclength == 1 || req_caseopt == 0) { firstchar = mcbuffer[0] | req_caseopt; if (mclength != 1) reqchar = code[-1] | cd->req_varyopt; } else firstchar = reqchar = REQ_NONE; } /* firstchar was previously set; we can set reqchar only if the length is 1 or the matching is caseful. */ else { zerofirstchar = firstchar; zeroreqchar = reqchar; if (mclength == 1 || req_caseopt == 0) reqchar = code[-1] | req_caseopt | cd->req_varyopt; } break; /* End of literal character handling */ } } /* end of big loop */ /* Control never reaches here by falling through, only by a goto for all the error states. Pass back the position in the pattern so that it can be displayed to the user for diagnosing the error. */ FAILED: *ptrptr = ptr; return FALSE; } /************************************************* * Compile sequence of alternatives * *************************************************/ /* On entry, ptr is pointing past the bracket character, but on return it points to the closing bracket, or vertical bar, or end of string. The code variable is pointing at the byte into which the BRA operator has been stored. This function is used during the pre-compile phase when we are trying to find out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: options option bits, including any changes for this subpattern codeptr -> the address of the current code pointer ptrptr -> the address of the current pattern pointer errorcodeptr -> pointer to error code variable lookbehind TRUE if this is a lookbehind assertion reset_bracount TRUE to reset the count for each branch skipbytes skip this many bytes at start (for brackets and OP_COND) cond_depth depth of nesting for conditional subpatterns firstcharptr place to put the first required character, or a negative number reqcharptr place to put the last required character, or a negative number bcptr pointer to the chain of currently open branches cd points to the data block with tables pointers etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase Returns: TRUE on success */ static BOOL compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr, int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes, int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr, branch_chain *bcptr, compile_data *cd, int *lengthptr) { const pcre_uchar *ptr = *ptrptr; pcre_uchar *code = *codeptr; pcre_uchar *last_branch = code; pcre_uchar *start_bracket = code; pcre_uchar *reverse_count = NULL; open_capitem capitem; int capnumber = 0; pcre_int32 firstchar, reqchar; pcre_int32 branchfirstchar, branchreqchar; int length; int orig_bracount; int max_bracount; branch_chain bc; bc.outer = bcptr; bc.current_branch = code; firstchar = reqchar = REQ_UNSET; /* Accumulate the length for use in the pre-compile phase. Start with the length of the BRA and KET and any extra bytes that are required at the beginning. We accumulate in a local variable to save frequent testing of lenthptr for NULL. We cannot do this by looking at the value of code at the start and end of each alternative, because compiled items are discarded during the pre-compile phase so that the work space is not exceeded. */ length = 2 + 2*LINK_SIZE + skipbytes; /* WARNING: If the above line is changed for any reason, you must also change the code that abstracts option settings at the start of the pattern and makes them global. It tests the value of length for (2 + 2*LINK_SIZE) in the pre-compile phase to find out whether anything has yet been compiled or not. */ /* If this is a capturing subpattern, add to the chain of open capturing items so that we can detect them if (*ACCEPT) is encountered. This is also used to detect groups that contain recursive back references to themselves. Note that only OP_CBRA need be tested here; changing this opcode to one of its variants, e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */ if (*code == OP_CBRA) { capnumber = GET2(code, 1 + LINK_SIZE); capitem.number = capnumber; capitem.next = cd->open_caps; capitem.flag = FALSE; cd->open_caps = &capitem; } /* Offset is set zero to mark that this bracket is still open */ PUT(code, 1, 0); code += 1 + LINK_SIZE + skipbytes; /* Loop for each alternative branch */ orig_bracount = max_bracount = cd->bracount; for (;;) { /* For a (?| group, reset the capturing bracket count so that each branch uses the same numbers. */ if (reset_bracount) cd->bracount = orig_bracount; /* Set up dummy OP_REVERSE if lookbehind assertion */ if (lookbehind) { *code++ = OP_REVERSE; reverse_count = code; PUTINC(code, 0, 0); length += 1 + LINK_SIZE; } /* Now compile the branch; in the pre-compile phase its length gets added into the length. */ if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar, &branchreqchar, &bc, cond_depth, cd, (lengthptr == NULL)? NULL : &length)) { *ptrptr = ptr; return FALSE; } /* Keep the highest bracket count in case (?| was used and some branch has fewer than the rest. */ if (cd->bracount > max_bracount) max_bracount = cd->bracount; /* In the real compile phase, there is some post-processing to be done. */ if (lengthptr == NULL) { /* If this is the first branch, the firstchar and reqchar values for the branch become the values for the regex. */ if (*last_branch != OP_ALT) { firstchar = branchfirstchar; reqchar = branchreqchar; } /* If this is not the first branch, the first char and reqchar have to match the values from all the previous branches, except that if the previous value for reqchar didn't have REQ_VARY set, it can still match, and we set REQ_VARY for the regex. */ else { /* If we previously had a firstchar, but it doesn't match the new branch, we have to abandon the firstchar for the regex, but if there was previously no reqchar, it takes on the value of the old firstchar. */ if (firstchar >= 0 && firstchar != branchfirstchar) { if (reqchar < 0) reqchar = firstchar; firstchar = REQ_NONE; } /* If we (now or from before) have no firstchar, a firstchar from the branch becomes a reqchar if there isn't a branch reqchar. */ if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0) branchreqchar = branchfirstchar; /* Now ensure that the reqchars match */ if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY)) reqchar = REQ_NONE; else reqchar |= branchreqchar; /* To "or" REQ_VARY */ } /* If lookbehind, check that this branch matches a fixed-length string, and put the length into the OP_REVERSE item. Temporarily mark the end of the branch with OP_END. If the branch contains OP_RECURSE, the result is -3 because there may be forward references that we can't check here. Set a flag to cause another lookbehind check at the end. Why not do it all at the end? Because common, erroneous checks are picked up here and the offset of the problem can be shown. */ if (lookbehind) { int fixed_length; *code = OP_END; fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0, FALSE, cd); DPRINTF(("fixed length = %d\n", fixed_length)); if (fixed_length == -3) { cd->check_lookbehind = TRUE; } else if (fixed_length < 0) { *errorcodeptr = (fixed_length == -2)? ERR36 : (fixed_length == -4)? ERR70: ERR25; *ptrptr = ptr; return FALSE; } else { if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length; PUT(reverse_count, 0, fixed_length); } } } /* Reached end of expression, either ')' or end of pattern. In the real compile phase, go back through the alternative branches and reverse the chain of offsets, with the field in the BRA item now becoming an offset to the first alternative. If there are no alternatives, it points to the end of the group. The length in the terminating ket is always the length of the whole bracketed item. Return leaving the pointer at the terminating char. */ if (*ptr != CHAR_VERTICAL_LINE) { if (lengthptr == NULL) { int branch_length = (int)(code - last_branch); do { int prev_length = GET(last_branch, 1); PUT(last_branch, 1, branch_length); branch_length = prev_length; last_branch -= branch_length; } while (branch_length > 0); } /* Fill in the ket */ *code = OP_KET; PUT(code, 1, (int)(code - start_bracket)); code += 1 + LINK_SIZE; /* If it was a capturing subpattern, check to see if it contained any recursive back references. If so, we must wrap it in atomic brackets. In any event, remove the block from the chain. */ if (capnumber > 0) { if (cd->open_caps->flag) { memmove(start_bracket + 1 + LINK_SIZE, start_bracket, IN_UCHARS(code - start_bracket)); *start_bracket = OP_ONCE; code += 1 + LINK_SIZE; PUT(start_bracket, 1, (int)(code - start_bracket)); *code = OP_KET; PUT(code, 1, (int)(code - start_bracket)); code += 1 + LINK_SIZE; length += 2 + 2*LINK_SIZE; } cd->open_caps = cd->open_caps->next; } /* Retain the highest bracket number, in case resetting was used. */ cd->bracount = max_bracount; /* Set values to pass back */ *codeptr = code; *ptrptr = ptr; *firstcharptr = firstchar; *reqcharptr = reqchar; if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < length) { *errorcodeptr = ERR20; return FALSE; } *lengthptr += length; } return TRUE; } /* Another branch follows. In the pre-compile phase, we can move the code pointer back to where it was for the start of the first branch. (That is, pretend that each branch is the only one.) In the real compile phase, insert an ALT node. Its length field points back to the previous branch while the bracket remains open. At the end the chain is reversed. It's done like this so that the start of the bracket has a zero offset until it is closed, making it possible to detect recursion. */ if (lengthptr != NULL) { code = *codeptr + 1 + LINK_SIZE + skipbytes; length += 1 + LINK_SIZE; } else { *code = OP_ALT; PUT(code, 1, (int)(code - last_branch)); bc.current_branch = last_branch = code; code += 1 + LINK_SIZE; } ptr++; } /* Control never reaches here */ } /************************************************* * Check for anchored expression * *************************************************/ /* Try to find out if this is an anchored regular expression. Consider each alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then it's anchored. However, if this is a multiline pattern, then only OP_SOD will be found, because ^ generates OP_CIRCM in that mode. We can also consider a regex to be anchored if OP_SOM starts all its branches. This is the code for \G, which means "match at start of match position, taking into account the match offset". A branch is also implicitly anchored if it starts with .* and DOTALL is set, because that will try the rest of the pattern at all possible matching points, so there is no point trying again.... er .... .... except when the .* appears inside capturing parentheses, and there is a subsequent back reference to those parentheses. We haven't enough information to catch that case precisely. At first, the best we could do was to detect when .* was in capturing brackets and the highest back reference was greater than or equal to that level. However, by keeping a bitmap of the first 31 back references, we can catch some of the more common cases more precisely. Arguments: code points to start of expression (the bracket) bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_anchored(register const pcre_uchar *code, unsigned int bracket_map, unsigned int backref_map) { do { const pcre_uchar *scode = first_significant_code( code + PRIV(OP_lengths)[*code], FALSE); register int op = *scode; /* Non-capturing brackets */ if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ else if (op == OP_CBRA || op == OP_CBRAPOS || op == OP_SCBRA || op == OP_SCBRAPOS) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); if (!is_anchored(scode, new_map, backref_map)) return FALSE; } /* Other brackets */ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC || op == OP_COND) { if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and it isn't in brackets that are or may be referenced. */ else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)) { if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0) return FALSE; } /* Check for explicit anchoring */ else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE; code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ return TRUE; } /************************************************* * Check for starting with ^ or .* * *************************************************/ /* This is called to find out if every branch starts with ^ or .* so that "first char" processing can be done to speed things up in multiline matching and for non-DOTALL patterns that start with .* (which must start at the beginning or after \n). As in the case of is_anchored() (see above), we have to take account of back references to capturing brackets that contain .* because in that case we can't make the assumption. Arguments: code points to start of expression (the bracket) bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_startline(const pcre_uchar *code, unsigned int bracket_map, unsigned int backref_map) { do { const pcre_uchar *scode = first_significant_code( code + PRIV(OP_lengths)[*code], FALSE); register int op = *scode; /* If we are at the start of a conditional assertion group, *both* the conditional assertion *and* what follows the condition must satisfy the test for start of line. Other kinds of condition fail. Note that there may be an auto-callout at the start of a condition. */ if (op == OP_COND) { scode += 1 + LINK_SIZE; if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT]; switch (*scode) { case OP_CREF: case OP_NCREF: case OP_RREF: case OP_NRREF: case OP_DEF: return FALSE; default: /* Assertion */ if (!is_startline(scode, bracket_map, backref_map)) return FALSE; do scode += GET(scode, 1); while (*scode == OP_ALT); scode += 1 + LINK_SIZE; break; } scode = first_significant_code(scode, FALSE); op = *scode; } /* Non-capturing brackets */ if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ else if (op == OP_CBRA || op == OP_CBRAPOS || op == OP_SCBRA || op == OP_SCBRAPOS) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); if (!is_startline(scode, new_map, backref_map)) return FALSE; } /* Other brackets */ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* .* means "start at start or after \n" if it isn't in brackets that may be referenced. */ else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) { if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; } /* Check for explicit circumflex */ else if (op != OP_CIRC && op != OP_CIRCM) return FALSE; /* Move on to the next alternative */ code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ return TRUE; } /************************************************* * Check for asserted fixed first char * *************************************************/ /* During compilation, the "first char" settings from forward assertions are discarded, because they can cause conflicts with actual literals that follow. However, if we end up without a first char setting for an unanchored pattern, it is worth scanning the regex to see if there is an initial asserted first char. If all branches start with the same asserted char, or with a bracket all of whose alternatives start with the same asserted char (recurse ad lib), then we return that char, otherwise -1. Arguments: code points to start of expression (the bracket) inassert TRUE if in an assertion Returns: -1 or the fixed first char */ static int find_firstassertedchar(const pcre_uchar *code, BOOL inassert) { register int c = -1; do { int d; int xl = (*code == OP_CBRA || *code == OP_SCBRA || *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0; const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE); register int op = *scode; switch(op) { default: return -1; case OP_BRA: case OP_BRAPOS: case OP_CBRA: case OP_SCBRA: case OP_CBRAPOS: case OP_SCBRAPOS: case OP_ASSERT: case OP_ONCE: case OP_ONCE_NC: case OP_COND: if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0) return -1; if (c < 0) c = d; else if (c != d) return -1; break; case OP_EXACT: scode += IMM2_SIZE; /* Fall through */ case OP_CHAR: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: if (!inassert) return -1; if (c < 0) c = scode[1]; else if (c != scode[1]) return -1; break; case OP_EXACTI: scode += IMM2_SIZE; /* Fall through */ case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: case OP_POSPLUSI: if (!inassert) return -1; if (c < 0) c = scode[1] | REQ_CASELESS; else if (c != scode[1]) return -1; break; } code += GET(code, 1); } while (*code == OP_ALT); return c; } /************************************************* * Compile a Regular Expression * *************************************************/ /* This function takes a string and returns a pointer to a block of store holding a compiled version of the expression. The original API for this function had no error code return variable; it is retained for backwards compatibility. The new function is given a new name. Arguments: pattern the regular expression options various option bits errorcodeptr pointer to error code variable (pcre_compile2() only) can be NULL if you don't want a code value errorptr pointer to pointer to error text erroroffset ptr offset in pattern where error was detected tables pointer to character tables or NULL Returns: pointer to compiled data block, or NULL on error, with errorptr and erroroffset set */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile(const char *pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) #else PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) #endif { #ifdef COMPILE_PCRE8 return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables); #else return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables); #endif } #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errorptr, int *erroroffset, const unsigned char *tables) #else PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr, const char **errorptr, int *erroroffset, const unsigned char *tables) #endif { REAL_PCRE *re; int length = 1; /* For final END opcode */ pcre_int32 firstchar, reqchar; int newline; int errorcode = 0; int skipatstart = 0; BOOL utf; size_t size; pcre_uchar *code; const pcre_uchar *codestart; const pcre_uchar *ptr; compile_data compile_block; compile_data *cd = &compile_block; /* This space is used for "compiling" into during the first phase, when we are computing the amount of memory that is needed. Compiled items are thrown away as soon as possible, so that a fairly large buffer should be sufficient for this purpose. The same space is used in the second phase for remembering where to fill in forward references to subpatterns. That may overflow, in which case new memory is obtained from malloc(). */ pcre_uchar cworkspace[COMPILE_WORK_SIZE]; /* Set this early so that early errors get offset 0. */ ptr = (const pcre_uchar *)pattern; /* We can't pass back an error message if errorptr is NULL; I guess the best we can do is just return NULL, but we can set a code value if there is a code pointer. */ if (errorptr == NULL) { if (errorcodeptr != NULL) *errorcodeptr = 99; return NULL; } *errorptr = NULL; if (errorcodeptr != NULL) *errorcodeptr = ERR0; /* However, we can give a message for this error */ if (erroroffset == NULL) { errorcode = ERR16; goto PCRE_EARLY_ERROR_RETURN2; } *erroroffset = 0; /* Set up pointers to the individual character tables */ if (tables == NULL) tables = PRIV(default_tables); cd->lcc = tables + lcc_offset; cd->fcc = tables + fcc_offset; cd->cbits = tables + cbits_offset; cd->ctypes = tables + ctypes_offset; /* Check that all undefined public option bits are zero */ if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0) { errorcode = ERR17; goto PCRE_EARLY_ERROR_RETURN; } /* Check for global one-time settings at the start of the pattern, and remember the offset for later. */ while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && ptr[skipatstart+1] == CHAR_ASTERISK) { int newnl = 0; int newbsr = 0; #ifdef COMPILE_PCRE8 if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0) { skipatstart += 7; options |= PCRE_UTF8; continue; } #endif #ifdef COMPILE_PCRE16 if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0) { skipatstart += 8; options |= PCRE_UTF16; continue; } #endif else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0) { skipatstart += 6; options |= PCRE_UCP; continue; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0) { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; } if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0) { skipatstart += 5; newnl = PCRE_NEWLINE_CR; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0) { skipatstart += 5; newnl = PCRE_NEWLINE_LF; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0) { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0) { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0) { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0) { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0) { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; } if (newnl != 0) options = (options & ~PCRE_NEWLINE_BITS) | newnl; else if (newbsr != 0) options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr; else break; } /* PCRE_UTF16 has the same value as PCRE_UTF8. */ utf = (options & PCRE_UTF8) != 0; /* Can't support UTF unless PCRE has been compiled to include the code. The return of an error code from PRIV(valid_utf)() is a new feature, introduced in release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is not used here. */ #ifdef SUPPORT_UTF if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 && (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0) { #ifdef COMPILE_PCRE8 errorcode = ERR44; #else errorcode = ERR74; #endif goto PCRE_EARLY_ERROR_RETURN2; } #else if (utf) { errorcode = ERR32; goto PCRE_EARLY_ERROR_RETURN; } #endif /* Can't support UCP unless PCRE has been compiled to include the code. */ #ifndef SUPPORT_UCP if ((options & PCRE_UCP) != 0) { errorcode = ERR67; goto PCRE_EARLY_ERROR_RETURN; } #endif /* Check validity of \R options. */ if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) { errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN; } /* Handle different types of newline. The three bits give seven cases. The current code allows for fixed one- or two-byte sequences, plus "any" and "anycrlf". */ switch (options & PCRE_NEWLINE_BITS) { case 0: newline = NEWLINE; break; /* Build-time default */ case PCRE_NEWLINE_CR: newline = CHAR_CR; break; case PCRE_NEWLINE_LF: newline = CHAR_NL; break; case PCRE_NEWLINE_CR+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break; case PCRE_NEWLINE_ANY: newline = -1; break; case PCRE_NEWLINE_ANYCRLF: newline = -2; break; default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN; } if (newline == -2) { cd->nltype = NLTYPE_ANYCRLF; } else if (newline < 0) { cd->nltype = NLTYPE_ANY; } else { cd->nltype = NLTYPE_FIXED; 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. The bitmap records up to 31 back references to help in deciding whether (.*) can be treated as anchored or not. */ cd->top_backref = 0; cd->backref_map = 0; /* Reflect pattern for debugging output */ DPRINTF(("------------------------------------------------------------------\n")); #ifdef PCRE_DEBUG print_puchar(stdout, (PCRE_PUCHAR)pattern); #endif DPRINTF(("\n")); /* Pretend to compile the pattern while actually just accumulating the length of memory required. This behaviour is triggered by passing a non-NULL final argument to compile_regex(). We pass a block of workspace (cworkspace) for it to compile parts of the pattern into; the compiled code is discarded when it is no longer needed, so hopefully this workspace will never overflow, though there is a test for its doing so. */ cd->bracount = cd->final_bracount = 0; cd->names_found = 0; cd->name_entry_size = 0; cd->name_table = NULL; cd->start_code = cworkspace; cd->hwm = cworkspace; cd->start_workspace = cworkspace; cd->workspace_size = COMPILE_WORK_SIZE; cd->start_pattern = (const pcre_uchar *)pattern; cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern)); cd->req_varyopt = 0; cd->assert_depth = 0; cd->max_lookbehind = 0; cd->external_options = options; cd->external_flags = 0; cd->open_caps = NULL; /* Now do the pre-compile. On error, errorcode will be set non-zero, so we don't need to look at the result of the function here. The initial options have been put into the cd block so that they can be changed if an option setting is found within the regex right at the beginning. Bringing initial option settings outside can help speed up starting point checks. */ ptr += skipatstart; code = cworkspace; *code = OP_BRA; (void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length); if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, (int)(cd->hwm - cworkspace))); if (length > MAX_PATTERN_SIZE) { errorcode = ERR20; goto PCRE_EARLY_ERROR_RETURN; } /* Compute the size of data block needed and get it, either from malloc or externally provided function. Integer overflow should no longer be possible because nowadays we limit the maximum value of cd->names_found and cd->name_entry_size. */ size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar); re = (REAL_PCRE *)(PUBL(malloc))(size); if (re == NULL) { errorcode = ERR21; goto PCRE_EARLY_ERROR_RETURN; } /* Put in the magic number, and save the sizes, initial options, internal flags, and character table pointer. NULL is used for the default character tables. The nullpad field is at the end; it's there to help in the case when a regex compiled on a system with 4-byte pointers is run on another with 8-byte pointers. */ re->magic_number = MAGIC_NUMBER; re->size = (int)size; re->options = cd->external_options; re->flags = cd->external_flags; re->first_char = 0; re->req_char = 0; re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar); re->name_entry_size = cd->name_entry_size; re->name_count = cd->names_found; re->ref_count = 0; re->tables = (tables == PRIV(default_tables))? NULL : tables; re->nullpad = NULL; /* The starting points of the name/number translation table and of the code are passed around in the compile data block. The start/end pattern and initial options are already set from the pre-compile phase, as is the name_entry_size field. Reset the bracket count and the names_found field. Also reset the hwm field; this time it's used for remembering forward references to subpatterns. */ cd->final_bracount = cd->bracount; /* Save for checking forward references */ cd->assert_depth = 0; cd->bracount = 0; cd->max_lookbehind = 0; cd->names_found = 0; cd->name_table = (pcre_uchar *)re + re->name_table_offset; codestart = cd->name_table + re->name_entry_size * re->name_count; cd->start_code = codestart; cd->hwm = (pcre_uchar *)(cd->start_workspace); cd->req_varyopt = 0; cd->had_accept = FALSE; cd->check_lookbehind = FALSE; cd->open_caps = NULL; /* 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 of the function here. */ ptr = (const pcre_uchar *)pattern + skipatstart; code = (pcre_uchar *)codestart; *code = OP_BRA; (void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, NULL); re->top_bracket = cd->bracount; re->top_backref = cd->top_backref; re->max_lookbehind = cd->max_lookbehind; re->flags = cd->external_flags | PCRE_MODE; if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */ /* If not reached end of pattern on success, there's an excess bracket. */ if (errorcode == 0 && *ptr != 0) errorcode = ERR22; /* Fill in the terminating state and check for disastrous overflow, but if debugging, leave the test till after things are printed out. */ *code++ = OP_END; #ifndef PCRE_DEBUG if (code - codestart > length) errorcode = ERR23; #endif /* Fill in any forward references that are required. There may be repeated references; optimize for them, as searching a large regex takes time. */ if (cd->hwm > cd->start_workspace) { int prev_recno = -1; const pcre_uchar *groupptr = NULL; while (errorcode == 0 && cd->hwm > cd->start_workspace) { int offset, recno; cd->hwm -= LINK_SIZE; offset = GET(cd->hwm, 0); recno = GET(codestart, offset); if (recno != prev_recno) { groupptr = PRIV(find_bracket)(codestart, utf, recno); prev_recno = recno; } if (groupptr == NULL) errorcode = ERR53; else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart)); } } /* If the workspace had to be expanded, free the new memory. */ if (cd->workspace_size > COMPILE_WORK_SIZE) (PUBL(free))((void *)cd->start_workspace); /* Give an error if there's back reference to a non-existent capturing subpattern. */ if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15; /* If there were any lookbehind assertions that contained OP_RECURSE (recursions or subroutine calls), a flag is set for them to be checked here, because they may contain forward references. Actual recursions can't be fixed length, but subroutine calls can. It is done like this so that those without OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The exceptional ones forgo this. We scan the pattern to check that they are fixed length, and set their lengths. */ if (cd->check_lookbehind) { pcre_uchar *cc = (pcre_uchar *)codestart; /* Loop, searching for OP_REVERSE items, and process those that do not have their length set. (Actually, it will also re-process any that have a length of zero, but that is a pathological case, and it does no harm.) When we find one, we temporarily terminate the branch it is in while we scan it. */ for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1); cc != NULL; cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1)) { if (GET(cc, 1) == 0) { int fixed_length; pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE); int end_op = *be; *be = OP_END; fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE, cd); *be = end_op; DPRINTF(("fixed length = %d\n", fixed_length)); if (fixed_length < 0) { errorcode = (fixed_length == -2)? ERR36 : (fixed_length == -4)? ERR70 : ERR25; break; } if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length; PUT(cc, 1, fixed_length); } cc += 1 + LINK_SIZE; } } /* Failed to compile, or error while post-processing */ if (errorcode != 0) { (PUBL(free))(re); PCRE_EARLY_ERROR_RETURN: *erroroffset = (int)(ptr - (const pcre_uchar *)pattern); PCRE_EARLY_ERROR_RETURN2: *errorptr = find_error_text(errorcode); if (errorcodeptr != NULL) *errorcodeptr = errorcode; return NULL; } /* If the anchored option was not passed, set the flag if we can determine that the pattern is anchored by virtue of ^ characters or \A or anything else (such as starting with .* when DOTALL is set). Otherwise, if we know what the first byte has to be, save it, because that speeds up unanchored matches no end. If not, see if we can set the PCRE_STARTLINE flag. This is helpful for multiline matches when all branches start with ^. and also when all branches start with .* for non-DOTALL matches. */ if ((re->options & PCRE_ANCHORED) == 0) { if (is_anchored(codestart, 0, cd->backref_map)) re->options |= PCRE_ANCHORED; else { if (firstchar < 0) firstchar = find_firstassertedchar(codestart, FALSE); if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */ { #ifdef COMPILE_PCRE8 re->first_char = firstchar & 0xff; #else #ifdef COMPILE_PCRE16 re->first_char = firstchar & 0xffff; #endif #endif if ((firstchar & REQ_CASELESS) != 0) { #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) /* We ignore non-ASCII first chars in 8 bit mode. */ if (utf) { if (re->first_char < 128) { if (cd->fcc[re->first_char] != re->first_char) re->flags |= PCRE_FCH_CASELESS; } else if (UCD_OTHERCASE(re->first_char) != re->first_char) re->flags |= PCRE_FCH_CASELESS; } else #endif if (MAX_255(re->first_char) && cd->fcc[re->first_char] != re->first_char) re->flags |= PCRE_FCH_CASELESS; } re->flags |= PCRE_FIRSTSET; } else if (is_startline(codestart, 0, cd->backref_map)) re->flags |= PCRE_STARTLINE; } } /* For an anchored pattern, we use the "required byte" only if it follows a variable length item in the regex. Remove the caseless flag for non-caseable bytes. */ if (reqchar >= 0 && ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0)) { #ifdef COMPILE_PCRE8 re->req_char = reqchar & 0xff; #else #ifdef COMPILE_PCRE16 re->req_char = reqchar & 0xffff; #endif #endif if ((reqchar & REQ_CASELESS) != 0) { #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) /* We ignore non-ASCII first chars in 8 bit mode. */ if (utf) { if (re->req_char < 128) { if (cd->fcc[re->req_char] != re->req_char) re->flags |= PCRE_RCH_CASELESS; } else if (UCD_OTHERCASE(re->req_char) != re->req_char) re->flags |= PCRE_RCH_CASELESS; } else #endif if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char) re->flags |= PCRE_RCH_CASELESS; } re->flags |= PCRE_REQCHSET; } /* Print out the compiled data if debugging is enabled. This is never the case when building a production library. */ #ifdef PCRE_DEBUG printf("Length = %d top_bracket = %d top_backref = %d\n", length, re->top_bracket, re->top_backref); printf("Options=%08x\n", re->options); if ((re->flags & PCRE_FIRSTSET) != 0) { pcre_uchar ch = re->first_char; const char *caseless = ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)"; if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless); else printf("First char = \\x%02x%s\n", ch, caseless); } if ((re->flags & PCRE_REQCHSET) != 0) { pcre_uchar ch = re->req_char; const char *caseless = ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)"; if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless); else printf("Req char = \\x%02x%s\n", ch, caseless); } #ifdef COMPILE_PCRE8 pcre_printint((pcre *)re, stdout, TRUE); #else pcre16_printint((pcre *)re, stdout, TRUE); #endif /* This check is done here in the debugging case so that the code that was compiled can be seen. */ if (code - codestart > length) { (PUBL(free))(re); *errorptr = find_error_text(ERR23); *erroroffset = ptr - (pcre_uchar *)pattern; if (errorcodeptr != NULL) *errorcodeptr = ERR23; return NULL; } #endif /* PCRE_DEBUG */ #ifdef COMPILE_PCRE8 return (pcre *)re; #else return (pcre16 *)re; #endif } /* End of pcre_compile.c */ pcre-8.31/pcre16_jit_compile.c0000644000222100022210000000421111676645227013143 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_jit_compile.c" /* End of pcre16_jit_compile.c */ pcre-8.31/RunTest0000755000222100022210000005731111721707220010643 00000000000000#! /bin/sh # Run the PCRE tests using the pcretest program. The appropriate tests are # selected, depending on which build-time options were used. # All tests are now run both with and without -s, to ensure that everything is # tested with and without studying. However, there are some tests that produce # different output after studying, typically when we are tracing the actual # matching process (for example, using auto-callouts). In these few cases, the # tests are duplicated in the files, one with /S to force studying always, and # one with /SS to force *not* studying always. The use of -s doesn't then make # any difference to their output. There is also one test which compiles invalid # UTF-8 with the UTF-8 check turned off; for this, studying must also be # disabled with /SS. # When JIT support is available, all the tests are also run with -s+ to test # (again, almost) everything with studying and the JIT option. There are also # two tests for JIT-specific features, one to be run when JIT support is # available, and one when it is not. # Whichever of the 8-bit and 16-bit libraries exist are tested. It is also # possible to select which to test by the arguments -8 or -16. # Other arguments for this script can be individual test numbers, or the word # "valgrind", or "sim" followed by an argument to run cross-compiled # executables under a simulator, for example: # # RunTest 3 sim "qemu-arm -s 8388608" # # Finally, if the script is obeyed as "RunTest list", a list of available # tests is output, but none of them are run. # Define test titles in variables so that they can be output as a list. Some # of them are modified (e.g. with -8 or -16) when used in the actual tests. title1="Test 1: Main functionality (Compatible with Perl >= 5.10)" title2="Test 2: API, errors, internals, and non-Perl stuff" title3="Test 3: Locale-specific features" title4A="Test 4: UTF" title4B=" support (Compatible with Perl >= 5.10)" title5="Test 5: API, internals, and non-Perl stuff for UTF" title6="Test 6: Unicode property support (Compatible with Perl >= 5.10)" title7="Test 7: API, internals, and non-Perl stuff for Unicode property support" title8="Test 8: DFA matching main functionality" title9="Test 9: DFA matching with UTF" title10="Test 10: DFA matching with Unicode properties" title11="Test 11: Internal offsets and code size tests" title12="Test 12: JIT-specific features (JIT available)" title13="Test 13: JIT-specific features (JIT not available)" title14="Test 14: Specials for the basic 8-bit library" title15="Test 15: Specials for the 8-bit library with UTF-8 support" title16="Test 16: Specials for the 8-bit library with Unicode propery support" title17="Test 17: Specials for the basic 16-bit library" title18="Test 18: Specials for the 16-bit library with UTF-16 support" title19="Test 19: Specials for the 16-bit library with Unicode propery support" title20="Test 20: DFA specials for the basic 16-bit library" title21="Test 21: Reloads for the basic 16-bit library" title22="Test 22: Reloads for the 16-bit library with UTF-16 support" if [ $# -eq 1 -a "$1" = "list" ]; then echo $title1 echo $title2 "(not UTF)" echo $title3 echo $title4A $title4B echo $title5 support echo $title6 echo $title7 echo $title8 echo $title9 echo $title10 echo $title11 echo $title12 echo $title13 echo $title14 echo $title15 echo $title16 echo $title17 echo $title18 echo $title19 echo $title20 echo $title21 echo $title22 exit 0 fi # Default values valgrind= sim= arg8= arg16= # This is in case the caller has set aliases (as I do - PH) unset cp ls mv rm # Select which tests to run; for those that are explicitly requested, check # that the necessary optional facilities are available. do1=no do2=no do3=no do4=no do5=no do6=no do7=no do8=no do9=no do10=no do11=no do12=no do13=no do14=no do15=no do16=no do17=no do18=no do19=no do20=no do21=no do22=no while [ $# -gt 0 ] ; do case $1 in 1) do1=yes;; 2) do2=yes;; 3) do3=yes;; 4) do4=yes;; 5) do5=yes;; 6) do6=yes;; 7) do7=yes;; 8) do8=yes;; 9) do9=yes;; 10) do10=yes;; 11) do11=yes;; 12) do12=yes;; 13) do13=yes;; 14) do14=yes;; 15) do15=yes;; 16) do16=yes;; 17) do17=yes;; 18) do18=yes;; 19) do19=yes;; 20) do20=yes;; 21) do21=yes;; 22) do22=yes;; -8) arg8=yes;; -16) arg16=yes;; valgrind) valgrind="valgrind -q --smc-check=all";; sim) shift; sim=$1;; *) echo "Unknown test number '$1'"; exit 1;; esac shift done # Set up a suitable "diff" command for comparison. Some systems # have a diff that lacks a -u option. Try to deal with this. if diff -u /dev/null /dev/null; then cf="diff -u"; else cf="diff"; fi # Find the test data if [ -n "$srcdir" -a -d "$srcdir" ] ; then testdata="$srcdir/testdata" elif [ -d "./testdata" ] ; then testdata=./testdata elif [ -d "../testdata" ] ; then testdata=../testdata else echo "Cannot find the testdata directory" exit 1 fi # Find which optional facilities are available. In some Windows environments # the output of pcretest -C has CRLF at the end of each line, but the shell # strips only linefeeds from the output of a `backquoted` command. Hence the # alternative patterns. $sim ./pcretest -C linksize >/dev/null link_size=$? if [ $link_size -lt 2 ] ; then echo "Failed to find internal link size" exit 1 fi if [ $link_size -gt 4 ] ; then echo "Failed to find internal link size" exit 1 fi # Both 8-bit and 16-bit character strings may be supported, but only one # need be. $sim ./pcretest -C pcre8 >/dev/null support8=$? $sim ./pcretest -C pcre16 >/dev/null support16=$? if [ `expr $support8 + $support16` -eq 2 ] ; then test8= test16=-16 if [ "$arg8" = yes -a "$arg16" != yes ] ; then test16=skip fi if [ "$arg16" = yes -a "$arg8" != yes ] ; then test8=skip fi else if [ $support8 -ne 0 ] ; then if [ "$arg16" = yes ] ; then echo "Cannot run 16-bit library tests: 16-bit library not compiled" exit 1 fi test8= test16=skip else if [ "$arg8" = yes ] ; then echo "Cannot run 8-bit library tests: 8-bit library not compiled" exit 1 fi test8=skip test16=-16 fi fi # UTF support always applies to both bit sizes if both are supported; we can't # have UTF-8 support without UTF-16 support (for example). $sim ./pcretest -C utf >/dev/null utf=$? $sim ./pcretest -C ucp >/dev/null ucp=$? jitopt= $sim ./pcretest -C jit >/dev/null jit=$? if [ $jit -ne 0 ] ; then jitopt=-s+ fi if [ $utf -eq 0 ] ; then if [ $do4 = yes ] ; then echo "Can't run test 4 because UTF support is not configured" exit 1 fi if [ $do5 = yes ] ; then echo "Can't run test 5 because UTF support is not configured" exit 1 fi if [ $do9 = yes ] ; then echo "Can't run test 8 because UTF support is not configured" exit 1 fi if [ $do15 = yes ] ; then echo "Can't run test 15 because UTF support is not configured" exit 1 fi if [ $do18 = yes ] ; then echo "Can't run test 18 because UTF support is not configured" fi if [ $do22 = yes ] ; then echo "Can't run test 22 because UTF support is not configured" fi fi if [ $ucp -eq 0 ] ; then if [ $do6 = yes ] ; then echo "Can't run test 6 because Unicode property support is not configured" exit 1 fi if [ $do7 = yes ] ; then echo "Can't run test 7 because Unicode property support is not configured" exit 1 fi if [ $do10 = yes ] ; then echo "Can't run test 10 because Unicode property support is not configured" exit 1 fi if [ $do16 = yes ] ; then echo "Can't run test 16 because Unicode property support is not configured" exit 1 fi if [ $do19 = yes ] ; then echo "Can't run test 19 because Unicode property support is not configured" exit 1 fi fi if [ $link_size -ne 2 ] ; then if [ $do11 = yes ] ; then echo "Can't run test 11 because the link size ($link_size) is not 2" exit 1 fi fi if [ $jit -eq 0 ] ; then if [ $do12 = "yes" ] ; then echo "Can't run test 12 because JIT support is not configured" exit 1 fi else if [ $do13 = "yes" ] ; then echo "Can't run test 13 because JIT support is configured" exit 1 fi fi # If no specific tests were requested, select all. Those that are not # relevant will be skipped. if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \ $do5 = no -a $do6 = no -a $do7 = no -a $do8 = no -a \ $do9 = no -a $do10 = no -a $do11 = no -a $do12 = no -a \ $do13 = no -a $do14 = no -a $do15 = no -a $do16 = no -a \ $do17 = no -a $do18 = no -a $do19 = no -a $do20 = no -a \ $do21 = no -a $do22 = no ] ; then do1=yes do2=yes do3=yes do4=yes do5=yes do6=yes do7=yes do8=yes do9=yes do10=yes do11=yes do12=yes do13=yes do14=yes do15=yes do16=yes do17=yes do18=yes do19=yes do20=yes do21=yes do22=yes fi # Show which release and which test data echo "" echo PCRE C library tests using test data from $testdata $sim ./pcretest /dev/null for bmode in "$test8" "$test16"; do case "$bmode" in skip) continue;; -16) if [ "$test8" != "skip" ] ; then echo ""; fi bits=16; echo "---- Testing 16-bit library ----"; echo "";; *) bits=8; echo "---- Testing 8-bit library ----"; echo "";; esac # Primary test, compatible with JIT and all versions of Perl >= 5.8 if [ $do1 = yes ] ; then echo $title1 for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput1 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput1 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi # PCRE tests that are not JIT or Perl-compatible: API, errors, internals if [ $do2 = yes ] ; then echo $title2 "(not UTF-$bits)" for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput2 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput2 testtry if [ $? != 0 ] ; then exit 1; fi else echo " " echo "** Test 2 requires a lot of stack. If it has crashed with a" echo "** segmentation fault, it may be that you do not have enough" echo "** stack available by default. Please see the 'pcrestack' man" echo "** page for a discussion of PCRE's stack usage." echo " " exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi # Locale-specific tests, provided that either the "fr_FR" or the "french" # locale is available. The former is the Unix-like standard; the latter is # for Windows. Another possibility is "fr", which needs to be run against # the Windows-specific input and output files. if [ $do3 = yes ] ; then locale -a | grep '^fr_FR$' >/dev/null if [ $? -eq 0 ] ; then locale=fr_FR infile=$testdata/testinput3 outfile=$testdata/testoutput3 else infile=test3input outfile=test3output locale -a | grep '^french$' >/dev/null if [ $? -eq 0 ] ; then locale=french sed 's/fr_FR/french/' $testdata/testinput3 >test3input sed 's/fr_FR/french/' $testdata/testoutput3 >test3output else locale -a | grep '^fr$' >/dev/null if [ $? -eq 0 ] ; then locale=fr sed 's/fr_FR/fr/' $testdata/wintestinput3 >test3input sed 's/fr_FR/fr/' $testdata/wintestoutput3 >test3output else locale= fi fi fi if [ "$locale" != "" ] ; then echo $title3 "(using '$locale' locale)" for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $infile testtry if [ $? = 0 ] ; then $cf $outfile testtry if [ $? != 0 ] ; then echo " " echo "Locale test did not run entirely successfully." echo "This usually means that there is a problem with the locale" echo "settings rather than a bug in PCRE." break; else if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi fi else exit 1 fi done else echo "Cannot test locale-specific features - none of the 'fr_FR', 'fr' or" echo "'french' locales exist, or the \"locale\" command is not available" echo "to check for them." echo " " fi fi # Additional tests for UTF support if [ $do4 = yes ] ; then echo ${title4A}-${bits}${title4B} if [ $utf -eq 0 ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput4 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput4 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi if [ $do5 = yes ] ; then echo ${title5}-${bits} support if [ $utf -eq 0 ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput5 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput5 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi if [ $do6 = yes ] ; then echo $title6 if [ $utf -eq 0 -o $ucp -eq 0 ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput6 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput6 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Test non-Perl-compatible Unicode property support if [ $do7 = yes ] ; then echo $title7 if [ $utf -eq 0 -o $ucp -eq 0 ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput7 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput7 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Tests for DFA matching support if [ $do8 = yes ] ; then echo $title8 for opt in "" "-s"; do $sim $valgrind ./pcretest -q $bmode $opt -dfa $testdata/testinput8 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput8 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi done fi if [ $do9 = yes ] ; then echo ${title9}-${bits} if [ $utf -eq 0 ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s"; do $sim $valgrind ./pcretest -q $bmode $opt -dfa $testdata/testinput9 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput9 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi done fi fi if [ $do10 = yes ] ; then echo $title10 if [ $utf -eq 0 -o $ucp -eq 0 ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s"; do $sim $valgrind ./pcretest -q $bmode $opt -dfa $testdata/testinput10 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput10 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi done fi fi # Test of internal offsets and code sizes. This test is run only when there # is Unicode property support and the link size is 2. The actual tests are # mostly the same as in some of the above, but in this test we inspect some # offsets and sizes that require a known link size. This is a doublecheck for # the maintainer, just in case something changes unexpectely. The output from # this test is not the same in 8-bit and 16-bit modes. if [ $do11 = yes ] ; then echo $title11 if [ $link_size -ne 2 ] ; then echo " Skipped because link size is not 2" elif [ $ucp -eq 0 ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s"; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput11 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput11-$bits testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi done fi fi # Test JIT-specific features when JIT is available if [ $do12 = yes ] ; then echo $title12 if [ $jit -eq 0 ] ; then echo " Skipped because JIT is not available or not usable" else $sim $valgrind ./pcretest -q $bmode $testdata/testinput12 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput12 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo " OK" fi fi # Test JIT-specific features when JIT is not available if [ $do13 = yes ] ; then echo $title13 if [ $jit -ne 0 ] ; then echo " Skipped because JIT is available" else $sim $valgrind ./pcretest -q $bmode $testdata/testinput13 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput13 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo " OK" fi fi # Tests for 8-bit-specific features if [ "$do14" = yes ] ; then echo $title14 if [ "$bits" = "16" ] ; then echo " Skipped when running 16-bit tests" else cp -f $testdata/saved16 testsaved16 for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput14 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput14 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Tests for 8-bit-specific features (needs UTF-8 support) if [ "$do15" = yes ] ; then echo $title15 if [ "$bits" = "16" ] ; then echo " Skipped when running 16-bit tests" elif [ $utf -eq 0 ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput15 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput15 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Tests for 8-bit-specific features (Unicode property support) if [ $do16 = yes ] ; then echo $title16 if [ "$bits" = "16" ] ; then echo " Skipped when running 16-bit tests" elif [ $ucp -eq 0 ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput16 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput16 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Tests for 16-bit-specific features if [ $do17 = yes ] ; then echo $title17 if [ "$bits" = "8" ] ; then echo " Skipped when running 8-bit tests" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput17 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput17 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Tests for 16-bit-specific features (UTF-16 support) if [ $do18 = yes ] ; then echo $title18 if [ "$bits" = "8" ] ; then echo " Skipped when running 8-bit tests" elif [ $utf -eq 0 ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput18 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput18 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Tests for 16-bit-specific features (Unicode property support) if [ $do19 = yes ] ; then echo $title19 if [ "$bits" = "8" ] ; then echo " Skipped when running 8-bit tests" elif [ $ucp -eq 0 ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput19 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput19 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi done fi fi # Tests for 16-bit-specific features in DFA non-UTF-16 mode if [ $do20 = yes ] ; then echo $title20 if [ "$bits" = "8" ] ; then echo " Skipped when running 8-bit tests" else for opt in "" "-s"; do $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput20 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput20 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi if [ "$opt" = "-s" ] ; then echo " OK with study" else echo " OK" fi done fi fi # Tests for reloads with 16-bit library if [ $do21 = yes ] ; then echo $title21 if [ "$bits" = "8" ] ; then echo " Skipped when running 8-bit tests" elif [ $link_size -ne 2 ] ; then echo " Skipped because link size is not 2" else cp -f $testdata/saved8 testsaved8 cp -f $testdata/saved16LE-1 testsaved16LE-1 cp -f $testdata/saved16BE-1 testsaved16BE-1 $sim $valgrind ./pcretest -q $bmode $testdata/testinput21 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput21 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo " OK" fi fi # Tests for reloads with 16-bit library (UTF-16 support) if [ $do22 = yes ] ; then echo $title22 if [ "$bits" = "8" ] ; then echo " Skipped when running 8-bit tests" elif [ $utf -eq 0 ] ; then echo " Skipped because UTF-$bits support is not available" elif [ $link_size -ne 2 ] ; then echo " Skipped because link size is not 2" else cp -f $testdata/saved16LE-2 testsaved16LE-2 cp -f $testdata/saved16BE-2 testsaved16BE-2 $sim $valgrind ./pcretest -q $bmode $testdata/testinput22 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput22 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo " OK" fi fi # End of loop for 8-bit/16-bit tests done # Clean up local working files rm -f test3input test3output testNinput testsaved* teststderr teststdout testtry # End pcre-8.31/pcrecpparg.h.in0000644000222100022210000001532110716100723012206 00000000000000// Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat #ifndef _PCRECPPARG_H #define _PCRECPPARG_H #include // for NULL #include #include namespace pcrecpp { class StringPiece; // Hex/Octal/Binary? // Special class for parsing into objects that define a ParseFrom() method template class _RE_MatchObject { public: static inline bool Parse(const char* str, int n, void* dest) { if (dest == NULL) return true; T* object = reinterpret_cast(dest); return object->ParseFrom(str, n); } }; class PCRECPP_EXP_DEFN Arg { public: // Empty constructor so we can declare arrays of Arg Arg(); // Constructor specially designed for NULL arguments Arg(void*); typedef bool (*Parser)(const char* str, int n, void* dest); // Type-specific parsers #define PCRE_MAKE_PARSER(type,name) \ Arg(type* p) : arg_(p), parser_(name) { } \ Arg(type* p, Parser parser) : arg_(p), parser_(parser) { } PCRE_MAKE_PARSER(char, parse_char); PCRE_MAKE_PARSER(unsigned char, parse_uchar); PCRE_MAKE_PARSER(short, parse_short); PCRE_MAKE_PARSER(unsigned short, parse_ushort); PCRE_MAKE_PARSER(int, parse_int); PCRE_MAKE_PARSER(unsigned int, parse_uint); PCRE_MAKE_PARSER(long, parse_long); PCRE_MAKE_PARSER(unsigned long, parse_ulong); #if @pcre_have_long_long@ PCRE_MAKE_PARSER(long long, parse_longlong); #endif #if @pcre_have_ulong_long@ PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong); #endif PCRE_MAKE_PARSER(float, parse_float); PCRE_MAKE_PARSER(double, parse_double); PCRE_MAKE_PARSER(std::string, parse_string); PCRE_MAKE_PARSER(StringPiece, parse_stringpiece); #undef PCRE_MAKE_PARSER // Generic constructor template Arg(T*, Parser parser); // Generic constructor template template Arg(T* p) : arg_(p), parser_(_RE_MatchObject::Parse) { } // Parse the data bool Parse(const char* str, int n) const; private: void* arg_; Parser parser_; static bool parse_null (const char* str, int n, void* dest); static bool parse_char (const char* str, int n, void* dest); static bool parse_uchar (const char* str, int n, void* dest); static bool parse_float (const char* str, int n, void* dest); static bool parse_double (const char* str, int n, void* dest); static bool parse_string (const char* str, int n, void* dest); static bool parse_stringpiece (const char* str, int n, void* dest); #define PCRE_DECLARE_INTEGER_PARSER(name) \ private: \ static bool parse_ ## name(const char* str, int n, void* dest); \ static bool parse_ ## name ## _radix( \ const char* str, int n, void* dest, int radix); \ public: \ static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \ static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \ static bool parse_ ## name ## _cradix(const char* str, int n, void* dest) PCRE_DECLARE_INTEGER_PARSER(short); PCRE_DECLARE_INTEGER_PARSER(ushort); PCRE_DECLARE_INTEGER_PARSER(int); PCRE_DECLARE_INTEGER_PARSER(uint); PCRE_DECLARE_INTEGER_PARSER(long); PCRE_DECLARE_INTEGER_PARSER(ulong); PCRE_DECLARE_INTEGER_PARSER(longlong); PCRE_DECLARE_INTEGER_PARSER(ulonglong); #undef PCRE_DECLARE_INTEGER_PARSER }; inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } inline bool Arg::Parse(const char* str, int n) const { return (*parser_)(str, n, arg_); } // This part of the parser, appropriate only for ints, deals with bases #define MAKE_INTEGER_PARSER(type, name) \ inline Arg Hex(type* ptr) { \ return Arg(ptr, Arg::parse_ ## name ## _hex); } \ inline Arg Octal(type* ptr) { \ return Arg(ptr, Arg::parse_ ## name ## _octal); } \ inline Arg CRadix(type* ptr) { \ return Arg(ptr, Arg::parse_ ## name ## _cradix); } MAKE_INTEGER_PARSER(short, short) /* */ MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ MAKE_INTEGER_PARSER(long, long) /* because they can cause */ MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ #if @pcre_have_long_long@ /* the checking level is */ MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ #endif /* */ #if @pcre_have_ulong_long@ /* */ MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */ #endif #undef PCRE_IS_SET #undef PCRE_SET_OR_CLEAR #undef MAKE_INTEGER_PARSER } // namespace pcrecpp #endif /* _PCRECPPARG_H */ pcre-8.31/makevp_c.txt0000644000222100022210000000047511676645217011656 00000000000000pcre_byte_order.c pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_info.c pcre_maketables.c pcre_newline.c pcre_ord2utf8.c pcre_refcount.c pcre_study.c pcre_tables.c pcre_ucd.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c pcre-8.31/makevp_l.txt0000644000222100022210000000106111676645223011654 00000000000000+pcre_byte_order.obj & +pcre_chartables.obj & +pcre_compile.obj & +pcre_config.obj & +pcre_dfa_exec.obj & +pcre_exec.obj & +pcre_fullinfo.obj & +pcre_get.obj & +pcre_globals.obj & +pcre_info.obj & +pcre_maketables.obj & +pcre_newline.obj & +pcre_ord2utf8.obj & +pcre_refcount.obj & +pcre_study.obj & +pcre_tables.obj & +pcre_ucd.obj & +pcre_valid_utf8.obj & +pcre_version.obj & +pcre_xclass.obj pcre-8.31/pcre16_compile.c0000644000222100022210000000420111676645212012266 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_compile.c" /* End of pcre16_compile.c */ pcre-8.31/pcre16_refcount.c0000644000222100022210000000420311676645226012472 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_refcount.c" /* End of pcre16_refcount.c */ pcre-8.31/pcre_scanner.cc0000644000222100022210000001265211401171122012250 00000000000000// Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "pcrecpp_internal.h" #include "pcre_scanner.h" using std::vector; namespace pcrecpp { Scanner::Scanner() : data_(), input_(data_), skip_(NULL), should_skip_(false), skip_repeat_(false), save_comments_(false), comments_(NULL), comments_offset_(0) { } Scanner::Scanner(const string& in) : data_(in), input_(data_), skip_(NULL), should_skip_(false), skip_repeat_(false), save_comments_(false), comments_(NULL), comments_offset_(0) { } Scanner::~Scanner() { delete skip_; delete comments_; } void Scanner::SetSkipExpression(const char* re) { delete skip_; if (re != NULL) { skip_ = new RE(re); should_skip_ = true; skip_repeat_ = true; ConsumeSkip(); } else { skip_ = NULL; should_skip_ = false; skip_repeat_ = false; } } void Scanner::Skip(const char* re) { delete skip_; if (re != NULL) { skip_ = new RE(re); should_skip_ = true; skip_repeat_ = false; ConsumeSkip(); } else { skip_ = NULL; should_skip_ = false; skip_repeat_ = false; } } void Scanner::DisableSkip() { assert(skip_ != NULL); should_skip_ = false; } void Scanner::EnableSkip() { assert(skip_ != NULL); should_skip_ = true; ConsumeSkip(); } int Scanner::LineNumber() const { // TODO: Make it more efficient by keeping track of the last point // where we computed line numbers and counting newlines since then. // We could use std:count, but not all systems have it. :-( int count = 1; for (const char* p = data_.data(); p < input_.data(); ++p) if (*p == '\n') ++count; return count; } int Scanner::Offset() const { return (int)(input_.data() - data_.c_str()); } bool Scanner::LookingAt(const RE& re) const { int consumed; return re.DoMatch(input_, RE::ANCHOR_START, &consumed, 0, 0); } bool Scanner::Consume(const RE& re, const Arg& arg0, const Arg& arg1, const Arg& arg2) { const bool result = re.Consume(&input_, arg0, arg1, arg2); if (result && should_skip_) ConsumeSkip(); return result; } // helper function to consume *skip_ and honour save_comments_ void Scanner::ConsumeSkip() { const char* start_data = input_.data(); while (skip_->Consume(&input_)) { if (!skip_repeat_) { // Only one skip allowed. break; } } if (save_comments_) { if (comments_ == NULL) { comments_ = new vector; } // already pointing one past end, so no need to +1 int length = (int)(input_.data() - start_data); if (length > 0) { comments_->push_back(StringPiece(start_data, length)); } } } void Scanner::GetComments(int start, int end, vector *ranges) { // short circuit out if we've not yet initialized comments_ // (e.g., when save_comments is false) if (!comments_) { return; } // TODO: if we guarantee that comments_ will contain StringPieces // that are ordered by their start, then we can do a binary search // for the first StringPiece at or past start and then scan for the // ones contained in the range, quit early (use equal_range or // lower_bound) for (vector::const_iterator it = comments_->begin(); it != comments_->end(); ++it) { if ((it->data() >= data_.c_str() + start && it->data() + it->size() <= data_.c_str() + end)) { ranges->push_back(*it); } } } void Scanner::GetNextComments(vector *ranges) { // short circuit out if we've not yet initialized comments_ // (e.g., when save_comments is false) if (!comments_) { return; } for (vector::const_iterator it = comments_->begin() + comments_offset_; it != comments_->end(); ++it) { ranges->push_back(*it); ++comments_offset_; } } } // namespace pcrecpp pcre-8.31/pcre_config.c0000644000222100022210000001056011705300547011731 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_config(). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Keep the original link size. */ static int real_link_size = LINK_SIZE; #include "pcre_internal.h" /************************************************* * Return info about what features are configured * *************************************************/ /* This function has an extensible interface so that additional items can be added compatibly. Arguments: what what information is required where where to put the information Returns: 0 if data returned, negative on error */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_config(int what, void *where) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_config(int what, void *where) #endif { switch (what) { case PCRE_CONFIG_UTF8: #if defined COMPILE_PCRE16 *((int *)where) = 0; return PCRE_ERROR_BADOPTION; #else #if defined SUPPORT_UTF *((int *)where) = 1; #else *((int *)where) = 0; #endif break; #endif case PCRE_CONFIG_UTF16: #if defined COMPILE_PCRE8 *((int *)where) = 0; return PCRE_ERROR_BADOPTION; #else #if defined SUPPORT_UTF *((int *)where) = 1; #else *((int *)where) = 0; #endif break; #endif case PCRE_CONFIG_UNICODE_PROPERTIES: #ifdef SUPPORT_UCP *((int *)where) = 1; #else *((int *)where) = 0; #endif break; case PCRE_CONFIG_JIT: #ifdef SUPPORT_JIT *((int *)where) = 1; #else *((int *)where) = 0; #endif break; case PCRE_CONFIG_JITTARGET: #ifdef SUPPORT_JIT *((const char **)where) = PRIV(jit_get_target)(); #else *((const char **)where) = NULL; #endif break; case PCRE_CONFIG_NEWLINE: *((int *)where) = NEWLINE; break; case PCRE_CONFIG_BSR: #ifdef BSR_ANYCRLF *((int *)where) = 1; #else *((int *)where) = 0; #endif break; case PCRE_CONFIG_LINK_SIZE: *((int *)where) = real_link_size; break; case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD: *((int *)where) = POSIX_MALLOC_THRESHOLD; break; case PCRE_CONFIG_MATCH_LIMIT: *((unsigned long int *)where) = MATCH_LIMIT; break; case PCRE_CONFIG_MATCH_LIMIT_RECURSION: *((unsigned long int *)where) = MATCH_LIMIT_RECURSION; break; case PCRE_CONFIG_STACKRECURSE: #ifdef NO_RECURSE *((int *)where) = 0; #else *((int *)where) = 1; #endif break; default: return PCRE_ERROR_BADOPTION; } return 0; } /* End of pcre_config.c */ pcre-8.31/pcre16_byte_order.c0000644000222100022210000000420711676645217013007 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_byte_order.c" /* End of pcre16_byte_order.c */ pcre-8.31/pcre16_get.c0000644000222100022210000000417111676645216011427 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_get.c" /* End of pcre16_get.c */ pcre-8.31/AUTHORS0000644000222100022210000000152311676645212010366 00000000000000THE MAIN PCRE LIBRARY --------------------- Written by: Philip Hazel Email local part: ph10 Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. Copyright (c) 1997-2012 University of Cambridge All rights reserved PCRE JUST-IN-TIME COMPILATION SUPPORT ------------------------------------- Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu Copyright(c) 2010-2012 Zoltan Herczeg All rights reserved. STACK-LESS JUST-IN-TIME COMPILER -------------------------------- Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu Copyright(c) 2009-2012 Zoltan Herczeg All rights reserved. THE C++ WRAPPER LIBRARY ----------------------- Written by: Google Inc. Copyright (c) 2007-2012 Google Inc All rights reserved #### pcre-8.31/pcre16_ucd.c0000644000222100022210000000417111676645226011424 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_ucd.c" /* End of pcre16_ucd.c */ pcre-8.31/pcre_tables.c0000644000222100022210000005414111762370424011745 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ #ifndef PCRE_INCLUDED /* This module contains some fixed tables that are used by more than one of the PCRE code modules. The tables are also #included by the pcretest program, which uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name clashes with the library. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" #endif /* PCRE_INCLUDED */ /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that the definition is next to the definition of the opcodes in pcre_internal.h. */ const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS }; /************************************************* * Tables for UTF-8 support * *************************************************/ /* These are the breakpoints for different numbers of bytes in a UTF-8 character. */ #if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \ || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16) /* These tables are also required by pcretest in 16 bit mode. */ const int PRIV(utf8_table1)[] = { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int); /* These are the indicator bits and the mask for the data bits to set in the first byte of a character, indexed by the number of additional bytes. */ const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; /* Table of the number of extra bytes, indexed by the first byte masked with 0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */ const pcre_uint8 PRIV(utf8_table4)[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; #endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/ #ifdef SUPPORT_UTF /* Table to translate from particular type value to the general value. */ const int PRIV(ucp_gentype)[] = { ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */ ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */ ucp_P, ucp_P, /* Ps, Po */ ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */ ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ }; #ifdef SUPPORT_JIT /* This table reverses PRIV(ucp_gentype). We can save the cost of a memory load. */ const int PRIV(ucp_typerange)[] = { ucp_Cc, ucp_Cs, ucp_Ll, ucp_Lu, ucp_Mc, ucp_Mn, ucp_Nd, ucp_No, ucp_Pc, ucp_Ps, ucp_Sc, ucp_So, ucp_Zl, ucp_Zs, }; #endif /* SUPPORT_JIT */ /* The pcre_utt[] table below translates Unicode property names into type and code values. It is searched by binary chop, so must be in collating sequence of name. Originally, the table contained pointers to the name strings in the first field of each entry. However, that leads to a large number of relocations when a shared library is dynamically loaded. A significant reduction is made by putting all the names into a single, large string and then using offsets in the table itself. Maintenance is more error-prone, but frequent changes to this data are unlikely. July 2008: There is now a script called maint/GenerateUtt.py that can be used to generate this data automatically instead of maintaining it by hand. The script was updated in March 2009 to generate a new EBCDIC-compliant version. Like all other character and string literals that are compared against the regular expression pattern, we must use STR_ macros instead of literal strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Any0 STR_A STR_n STR_y "\0" #define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0" #define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0" #define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0" #define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0" #define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0" #define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0" #define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0" #define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0" #define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0" #define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0" #define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0" #define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0" #define STRING_C0 STR_C "\0" #define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0" #define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0" #define STRING_Cc0 STR_C STR_c "\0" #define STRING_Cf0 STR_C STR_f "\0" #define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0" #define STRING_Cham0 STR_C STR_h STR_a STR_m "\0" #define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0" #define STRING_Cn0 STR_C STR_n "\0" #define STRING_Co0 STR_C STR_o "\0" #define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0" #define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0" #define STRING_Cs0 STR_C STR_s "\0" #define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0" #define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0" #define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0" #define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0" #define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0" #define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0" #define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0" #define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0" #define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0" #define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0" #define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0" #define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0" #define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0" #define STRING_Han0 STR_H STR_a STR_n "\0" #define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0" #define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0" #define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0" #define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0" #define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0" #define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0" #define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0" #define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0" #define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0" #define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0" #define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0" #define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0" #define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0" #define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0" #define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0" #define STRING_L0 STR_L "\0" #define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0" #define STRING_Lao0 STR_L STR_a STR_o "\0" #define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0" #define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0" #define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0" #define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0" #define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0" #define STRING_Ll0 STR_L STR_l "\0" #define STRING_Lm0 STR_L STR_m "\0" #define STRING_Lo0 STR_L STR_o "\0" #define STRING_Lt0 STR_L STR_t "\0" #define STRING_Lu0 STR_L STR_u "\0" #define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0" #define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0" #define STRING_M0 STR_M "\0" #define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0" #define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0" #define STRING_Mc0 STR_M STR_c "\0" #define STRING_Me0 STR_M STR_e "\0" #define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0" #define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0" #define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0" #define STRING_Miao0 STR_M STR_i STR_a STR_o "\0" #define STRING_Mn0 STR_M STR_n "\0" #define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0" #define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0" #define STRING_N0 STR_N "\0" #define STRING_Nd0 STR_N STR_d "\0" #define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0" #define STRING_Nko0 STR_N STR_k STR_o "\0" #define STRING_Nl0 STR_N STR_l "\0" #define STRING_No0 STR_N STR_o "\0" #define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0" #define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0" #define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0" #define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0" #define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0" #define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0" #define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0" #define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0" #define STRING_P0 STR_P "\0" #define STRING_Pc0 STR_P STR_c "\0" #define STRING_Pd0 STR_P STR_d "\0" #define STRING_Pe0 STR_P STR_e "\0" #define STRING_Pf0 STR_P STR_f "\0" #define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0" #define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0" #define STRING_Pi0 STR_P STR_i "\0" #define STRING_Po0 STR_P STR_o "\0" #define STRING_Ps0 STR_P STR_s "\0" #define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0" #define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0" #define STRING_S0 STR_S "\0" #define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0" #define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0" #define STRING_Sc0 STR_S STR_c "\0" #define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0" #define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0" #define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0" #define STRING_Sk0 STR_S STR_k "\0" #define STRING_Sm0 STR_S STR_m "\0" #define STRING_So0 STR_S STR_o "\0" #define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0" #define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0" #define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0" #define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0" #define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0" #define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0" #define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0" #define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0" #define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0" #define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0" #define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0" #define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0" #define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0" #define STRING_Thai0 STR_T STR_h STR_a STR_i "\0" #define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0" #define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0" #define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0" #define STRING_Vai0 STR_V STR_a STR_i "\0" #define STRING_Xan0 STR_X STR_a STR_n "\0" #define STRING_Xps0 STR_X STR_p STR_s "\0" #define STRING_Xsp0 STR_X STR_s STR_p "\0" #define STRING_Xwd0 STR_X STR_w STR_d "\0" #define STRING_Yi0 STR_Y STR_i "\0" #define STRING_Z0 STR_Z "\0" #define STRING_Zl0 STR_Z STR_l "\0" #define STRING_Zp0 STR_Z STR_p "\0" #define STRING_Zs0 STR_Z STR_s "\0" const char PRIV(utt_names)[] = STRING_Any0 STRING_Arabic0 STRING_Armenian0 STRING_Avestan0 STRING_Balinese0 STRING_Bamum0 STRING_Batak0 STRING_Bengali0 STRING_Bopomofo0 STRING_Brahmi0 STRING_Braille0 STRING_Buginese0 STRING_Buhid0 STRING_C0 STRING_Canadian_Aboriginal0 STRING_Carian0 STRING_Cc0 STRING_Cf0 STRING_Chakma0 STRING_Cham0 STRING_Cherokee0 STRING_Cn0 STRING_Co0 STRING_Common0 STRING_Coptic0 STRING_Cs0 STRING_Cuneiform0 STRING_Cypriot0 STRING_Cyrillic0 STRING_Deseret0 STRING_Devanagari0 STRING_Egyptian_Hieroglyphs0 STRING_Ethiopic0 STRING_Georgian0 STRING_Glagolitic0 STRING_Gothic0 STRING_Greek0 STRING_Gujarati0 STRING_Gurmukhi0 STRING_Han0 STRING_Hangul0 STRING_Hanunoo0 STRING_Hebrew0 STRING_Hiragana0 STRING_Imperial_Aramaic0 STRING_Inherited0 STRING_Inscriptional_Pahlavi0 STRING_Inscriptional_Parthian0 STRING_Javanese0 STRING_Kaithi0 STRING_Kannada0 STRING_Katakana0 STRING_Kayah_Li0 STRING_Kharoshthi0 STRING_Khmer0 STRING_L0 STRING_L_AMPERSAND0 STRING_Lao0 STRING_Latin0 STRING_Lepcha0 STRING_Limbu0 STRING_Linear_B0 STRING_Lisu0 STRING_Ll0 STRING_Lm0 STRING_Lo0 STRING_Lt0 STRING_Lu0 STRING_Lycian0 STRING_Lydian0 STRING_M0 STRING_Malayalam0 STRING_Mandaic0 STRING_Mc0 STRING_Me0 STRING_Meetei_Mayek0 STRING_Meroitic_Cursive0 STRING_Meroitic_Hieroglyphs0 STRING_Miao0 STRING_Mn0 STRING_Mongolian0 STRING_Myanmar0 STRING_N0 STRING_Nd0 STRING_New_Tai_Lue0 STRING_Nko0 STRING_Nl0 STRING_No0 STRING_Ogham0 STRING_Ol_Chiki0 STRING_Old_Italic0 STRING_Old_Persian0 STRING_Old_South_Arabian0 STRING_Old_Turkic0 STRING_Oriya0 STRING_Osmanya0 STRING_P0 STRING_Pc0 STRING_Pd0 STRING_Pe0 STRING_Pf0 STRING_Phags_Pa0 STRING_Phoenician0 STRING_Pi0 STRING_Po0 STRING_Ps0 STRING_Rejang0 STRING_Runic0 STRING_S0 STRING_Samaritan0 STRING_Saurashtra0 STRING_Sc0 STRING_Sharada0 STRING_Shavian0 STRING_Sinhala0 STRING_Sk0 STRING_Sm0 STRING_So0 STRING_Sora_Sompeng0 STRING_Sundanese0 STRING_Syloti_Nagri0 STRING_Syriac0 STRING_Tagalog0 STRING_Tagbanwa0 STRING_Tai_Le0 STRING_Tai_Tham0 STRING_Tai_Viet0 STRING_Takri0 STRING_Tamil0 STRING_Telugu0 STRING_Thaana0 STRING_Thai0 STRING_Tibetan0 STRING_Tifinagh0 STRING_Ugaritic0 STRING_Vai0 STRING_Xan0 STRING_Xps0 STRING_Xsp0 STRING_Xwd0 STRING_Yi0 STRING_Z0 STRING_Zl0 STRING_Zp0 STRING_Zs0; const ucp_type_table PRIV(utt)[] = { { 0, PT_ANY, 0 }, { 4, PT_SC, ucp_Arabic }, { 11, PT_SC, ucp_Armenian }, { 20, PT_SC, ucp_Avestan }, { 28, PT_SC, ucp_Balinese }, { 37, PT_SC, ucp_Bamum }, { 43, PT_SC, ucp_Batak }, { 49, PT_SC, ucp_Bengali }, { 57, PT_SC, ucp_Bopomofo }, { 66, PT_SC, ucp_Brahmi }, { 73, PT_SC, ucp_Braille }, { 81, PT_SC, ucp_Buginese }, { 90, PT_SC, ucp_Buhid }, { 96, PT_GC, ucp_C }, { 98, PT_SC, ucp_Canadian_Aboriginal }, { 118, PT_SC, ucp_Carian }, { 125, PT_PC, ucp_Cc }, { 128, PT_PC, ucp_Cf }, { 131, PT_SC, ucp_Chakma }, { 138, PT_SC, ucp_Cham }, { 143, PT_SC, ucp_Cherokee }, { 152, PT_PC, ucp_Cn }, { 155, PT_PC, ucp_Co }, { 158, PT_SC, ucp_Common }, { 165, PT_SC, ucp_Coptic }, { 172, PT_PC, ucp_Cs }, { 175, PT_SC, ucp_Cuneiform }, { 185, PT_SC, ucp_Cypriot }, { 193, PT_SC, ucp_Cyrillic }, { 202, PT_SC, ucp_Deseret }, { 210, PT_SC, ucp_Devanagari }, { 221, PT_SC, ucp_Egyptian_Hieroglyphs }, { 242, PT_SC, ucp_Ethiopic }, { 251, PT_SC, ucp_Georgian }, { 260, PT_SC, ucp_Glagolitic }, { 271, PT_SC, ucp_Gothic }, { 278, PT_SC, ucp_Greek }, { 284, PT_SC, ucp_Gujarati }, { 293, PT_SC, ucp_Gurmukhi }, { 302, PT_SC, ucp_Han }, { 306, PT_SC, ucp_Hangul }, { 313, PT_SC, ucp_Hanunoo }, { 321, PT_SC, ucp_Hebrew }, { 328, PT_SC, ucp_Hiragana }, { 337, PT_SC, ucp_Imperial_Aramaic }, { 354, PT_SC, ucp_Inherited }, { 364, PT_SC, ucp_Inscriptional_Pahlavi }, { 386, PT_SC, ucp_Inscriptional_Parthian }, { 409, PT_SC, ucp_Javanese }, { 418, PT_SC, ucp_Kaithi }, { 425, PT_SC, ucp_Kannada }, { 433, PT_SC, ucp_Katakana }, { 442, PT_SC, ucp_Kayah_Li }, { 451, PT_SC, ucp_Kharoshthi }, { 462, PT_SC, ucp_Khmer }, { 468, PT_GC, ucp_L }, { 470, PT_LAMP, 0 }, { 473, PT_SC, ucp_Lao }, { 477, PT_SC, ucp_Latin }, { 483, PT_SC, ucp_Lepcha }, { 490, PT_SC, ucp_Limbu }, { 496, PT_SC, ucp_Linear_B }, { 505, PT_SC, ucp_Lisu }, { 510, PT_PC, ucp_Ll }, { 513, PT_PC, ucp_Lm }, { 516, PT_PC, ucp_Lo }, { 519, PT_PC, ucp_Lt }, { 522, PT_PC, ucp_Lu }, { 525, PT_SC, ucp_Lycian }, { 532, PT_SC, ucp_Lydian }, { 539, PT_GC, ucp_M }, { 541, PT_SC, ucp_Malayalam }, { 551, PT_SC, ucp_Mandaic }, { 559, PT_PC, ucp_Mc }, { 562, PT_PC, ucp_Me }, { 565, PT_SC, ucp_Meetei_Mayek }, { 578, PT_SC, ucp_Meroitic_Cursive }, { 595, PT_SC, ucp_Meroitic_Hieroglyphs }, { 616, PT_SC, ucp_Miao }, { 621, PT_PC, ucp_Mn }, { 624, PT_SC, ucp_Mongolian }, { 634, PT_SC, ucp_Myanmar }, { 642, PT_GC, ucp_N }, { 644, PT_PC, ucp_Nd }, { 647, PT_SC, ucp_New_Tai_Lue }, { 659, PT_SC, ucp_Nko }, { 663, PT_PC, ucp_Nl }, { 666, PT_PC, ucp_No }, { 669, PT_SC, ucp_Ogham }, { 675, PT_SC, ucp_Ol_Chiki }, { 684, PT_SC, ucp_Old_Italic }, { 695, PT_SC, ucp_Old_Persian }, { 707, PT_SC, ucp_Old_South_Arabian }, { 725, PT_SC, ucp_Old_Turkic }, { 736, PT_SC, ucp_Oriya }, { 742, PT_SC, ucp_Osmanya }, { 750, PT_GC, ucp_P }, { 752, PT_PC, ucp_Pc }, { 755, PT_PC, ucp_Pd }, { 758, PT_PC, ucp_Pe }, { 761, PT_PC, ucp_Pf }, { 764, PT_SC, ucp_Phags_Pa }, { 773, PT_SC, ucp_Phoenician }, { 784, PT_PC, ucp_Pi }, { 787, PT_PC, ucp_Po }, { 790, PT_PC, ucp_Ps }, { 793, PT_SC, ucp_Rejang }, { 800, PT_SC, ucp_Runic }, { 806, PT_GC, ucp_S }, { 808, PT_SC, ucp_Samaritan }, { 818, PT_SC, ucp_Saurashtra }, { 829, PT_PC, ucp_Sc }, { 832, PT_SC, ucp_Sharada }, { 840, PT_SC, ucp_Shavian }, { 848, PT_SC, ucp_Sinhala }, { 856, PT_PC, ucp_Sk }, { 859, PT_PC, ucp_Sm }, { 862, PT_PC, ucp_So }, { 865, PT_SC, ucp_Sora_Sompeng }, { 878, PT_SC, ucp_Sundanese }, { 888, PT_SC, ucp_Syloti_Nagri }, { 901, PT_SC, ucp_Syriac }, { 908, PT_SC, ucp_Tagalog }, { 916, PT_SC, ucp_Tagbanwa }, { 925, PT_SC, ucp_Tai_Le }, { 932, PT_SC, ucp_Tai_Tham }, { 941, PT_SC, ucp_Tai_Viet }, { 950, PT_SC, ucp_Takri }, { 956, PT_SC, ucp_Tamil }, { 962, PT_SC, ucp_Telugu }, { 969, PT_SC, ucp_Thaana }, { 976, PT_SC, ucp_Thai }, { 981, PT_SC, ucp_Tibetan }, { 989, PT_SC, ucp_Tifinagh }, { 998, PT_SC, ucp_Ugaritic }, { 1007, PT_SC, ucp_Vai }, { 1011, PT_ALNUM, 0 }, { 1015, PT_PXSPACE, 0 }, { 1019, PT_SPACE, 0 }, { 1023, PT_WORD, 0 }, { 1027, PT_SC, ucp_Yi }, { 1030, PT_GC, ucp_Z }, { 1032, PT_PC, ucp_Zl }, { 1035, PT_PC, ucp_Zp }, { 1038, PT_PC, ucp_Zs } }; const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); #endif /* SUPPORT_UTF */ /* End of pcre_tables.c */ pcre-8.31/pcre16_exec.c0000644000222100022210000000417311676645227011600 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_exec.c" /* End of pcre16_exec.c */ pcre-8.31/pcre16_string_utils.c0000644000222100022210000000421311676645227013375 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_string_utils.c" /* End of pcre16_string_utils.c */ pcre-8.31/libpcrecpp.pc.in0000644000222100022210000000044011247244713012362 00000000000000# Package Information for pkg-config prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpcrecpp Description: PCRECPP - C++ wrapper for PCRE Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpcre -lpcrecpp Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ pcre-8.31/INSTALL0000644000222100022210000003633211775524614010357 00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. pcre-8.31/libpcre.pc.in0000644000222100022210000000050611676645226011674 00000000000000# Package Information for pkg-config prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpcre Description: PCRE - Perl compatible regular expressions C library with 8 bit character support Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpcre Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ pcre-8.31/pcre.h.generic0000644000222100022210000005552211775533031012036 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The current PCRE version information. */ #define PCRE_MAJOR 8 #define PCRE_MINOR 31 #define PCRE_PRERELEASE #define PCRE_DATE 2012-07-06 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export setting is defined in pcre_internal.h, which includes this file. So we don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # ifndef PCRE_EXP_DECL # define PCRE_EXP_DECL extern __declspec(dllimport) # endif # ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern __declspec(dllimport) # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN __declspec(dllimport) # endif # endif #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCRE_EXP_DECL # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif #endif #ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN # endif #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options. Some are compile-time only, some are run-time only, and some are both, so we keep them all distinct. However, almost all the bits in the options word are now used. In the long run, we may have to re-use some of the compile-time only bits for runtime options, or vice versa. In the comments below, "compile", "exec", and "DFA exec" mean that the option is permitted to be set for those functions; "used in" means that an option may be set only for compile, but is subsequently referenced in exec and/or DFA exec. Any of the compile-time options may be inspected during studying (and therefore JIT compiling). */ #define PCRE_CASELESS 0x00000001 /* Compile */ #define PCRE_MULTILINE 0x00000002 /* Compile */ #define PCRE_DOTALL 0x00000004 /* Compile */ #define PCRE_EXTENDED 0x00000008 /* Compile */ #define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */ #define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */ #define PCRE_EXTRA 0x00000040 /* Compile */ #define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */ #define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */ #define PCRE_UNGREEDY 0x00000200 /* Compile */ #define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */ /* The next two are also used in exec and DFA exec */ #define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */ #define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */ #define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ /* The next two are also used in exec and DFA exec */ #define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */ #define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */ #define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ #define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */ #define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ #define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */ #define PCRE_DFA_RESTART 0x00020000 /* DFA exec */ #define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */ #define PCRE_DUPNAMES 0x00080000 /* Compile */ #define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */ #define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */ #define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */ #define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */ #define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */ #define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */ #define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */ #define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */ #define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */ /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_OPCODE (-5) #define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */ #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) #define PCRE_ERROR_DFA_UITEM (-16) #define PCRE_ERROR_DFA_UCOND (-17) #define PCRE_ERROR_DFA_UMLIMIT (-18) #define PCRE_ERROR_DFA_WSSIZE (-19) #define PCRE_ERROR_DFA_RECURSE (-20) #define PCRE_ERROR_RECURSIONLIMIT (-21) #define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ #define PCRE_ERROR_BADNEWLINE (-23) #define PCRE_ERROR_BADOFFSET (-24) #define PCRE_ERROR_SHORTUTF8 (-25) #define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */ #define PCRE_ERROR_RECURSELOOP (-26) #define PCRE_ERROR_JIT_STACKLIMIT (-27) #define PCRE_ERROR_BADMODE (-28) #define PCRE_ERROR_BADENDIANNESS (-29) #define PCRE_ERROR_DFA_BADRESTART (-30) /* Specific error codes for UTF-8 validity checks */ #define PCRE_UTF8_ERR0 0 #define PCRE_UTF8_ERR1 1 #define PCRE_UTF8_ERR2 2 #define PCRE_UTF8_ERR3 3 #define PCRE_UTF8_ERR4 4 #define PCRE_UTF8_ERR5 5 #define PCRE_UTF8_ERR6 6 #define PCRE_UTF8_ERR7 7 #define PCRE_UTF8_ERR8 8 #define PCRE_UTF8_ERR9 9 #define PCRE_UTF8_ERR10 10 #define PCRE_UTF8_ERR11 11 #define PCRE_UTF8_ERR12 12 #define PCRE_UTF8_ERR13 13 #define PCRE_UTF8_ERR14 14 #define PCRE_UTF8_ERR15 15 #define PCRE_UTF8_ERR16 16 #define PCRE_UTF8_ERR17 17 #define PCRE_UTF8_ERR18 18 #define PCRE_UTF8_ERR19 19 #define PCRE_UTF8_ERR20 20 #define PCRE_UTF8_ERR21 21 /* Specific error codes for UTF-16 validity checks */ #define PCRE_UTF16_ERR0 0 #define PCRE_UTF16_ERR1 1 #define PCRE_UTF16_ERR2 2 #define PCRE_UTF16_ERR3 3 #define PCRE_UTF16_ERR4 4 /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 #define PCRE_INFO_OKPARTIAL 12 #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 #define PCRE_INFO_MINLENGTH 15 #define PCRE_INFO_JIT 16 #define PCRE_INFO_JITSIZE 17 #define PCRE_INFO_MAXLOOKBEHIND 18 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 #define PCRE_CONFIG_BSR 8 #define PCRE_CONFIG_JIT 9 #define PCRE_CONFIG_UTF16 10 #define PCRE_CONFIG_JITTARGET 11 /* Request types for pcre_study(). Do not re-arrange, in order to remain compatible. */ #define PCRE_STUDY_JIT_COMPILE 0x0001 #define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 #define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 /* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 #define PCRE_EXTRA_MARK 0x0020 #define PCRE_EXTRA_EXECUTABLE_JIT 0x0040 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; struct real_pcre16; /* declaration; the definition is private */ typedef struct real_pcre16 pcre16; struct real_pcre_jit_stack; /* declaration; the definition is private */ typedef struct real_pcre_jit_stack pcre_jit_stack; struct real_pcre16_jit_stack; /* declaration; the definition is private */ typedef struct real_pcre16_jit_stack pcre16_jit_stack; /* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain a 16 bit wide signed data type. Otherwise it can be a dummy data type since pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */ #ifndef PCRE_UCHAR16 #define PCRE_UCHAR16 unsigned short #endif #ifndef PCRE_SPTR16 #define PCRE_SPTR16 const PCRE_UCHAR16 * #endif /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ #ifndef PCRE_SPTR #define PCRE_SPTR const char * #endif /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ unsigned char **mark; /* For passing back a mark pointer */ void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre_extra; /* Same structure as above, but with 16 bit char pointers. */ typedef struct pcre16_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ PCRE_UCHAR16 **mark; /* For passing back a mark pointer */ void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre16_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------- Added for Version 2 -------------------------- */ const unsigned char *mark; /* Pointer to current mark or NULL */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Same structure as above, but with 16 bit char pointers. */ typedef struct pcre16_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR16 subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------- Added for Version 2 -------------------------- */ const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */ /* ------------------------------------------------------------------ */ } pcre16_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. For Virtual Pascal, these definitions have to take another form. */ #ifndef VPCOMPAT PCRE_EXP_DECL void *(*pcre_malloc)(size_t); PCRE_EXP_DECL void (*pcre_free)(void *); PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); PCRE_EXP_DECL void *(*pcre16_malloc)(size_t); PCRE_EXP_DECL void (*pcre16_free)(void *); PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre16_stack_free)(void *); PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); PCRE_EXP_DECL void *pcre16_malloc(size_t); PCRE_EXP_DECL void pcre16_free(void *); PCRE_EXP_DECL void *pcre16_stack_malloc(size_t); PCRE_EXP_DECL void pcre16_stack_free(void *); PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *); #endif /* VPCOMPAT */ /* User defined callback which provides a stack just before the match starts. */ typedef pcre_jit_stack *(*pcre_jit_callback)(void *); typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); PCRE_EXP_DECL int pcre16_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, int); PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int, PCRE_UCHAR16 *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *, PCRE_SPTR16, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *, PCRE_SPTR16, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); PCRE_EXP_DECL void pcre_free_substring_list(const char **); PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int, void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16, int *, int, PCRE_SPTR16, PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16, PCRE_UCHAR16 **, PCRE_UCHAR16 **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int, PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, PCRE_SPTR16 **); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **); PCRE_EXP_DECL void pcre_free_study(pcre_extra *); PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); PCRE_EXP_DECL const char *pcre_version(void); PCRE_EXP_DECL const char *pcre16_version(void); /* Utility functions for byte order swaps. */ PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *, const unsigned char *); PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *, const unsigned char *); PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, PCRE_SPTR16, int, int *, int); /* JIT compiler related functions. */ PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int); PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *); PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, pcre_jit_callback, void *); PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, pcre16_jit_callback, void *); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ pcre-8.31/config-cmake.h.in0000644000222100022210000000236611722461554012422 00000000000000/* config.h for CMake builds */ #cmakedefine HAVE_DIRENT_H 1 #cmakedefine HAVE_SYS_STAT_H 1 #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_WINDOWS_H 1 #cmakedefine HAVE_TYPE_TRAITS_H 1 #cmakedefine HAVE_BITS_TYPE_TRAITS_H 1 #cmakedefine HAVE_BCOPY 1 #cmakedefine HAVE_MEMMOVE 1 #cmakedefine HAVE_STRERROR 1 #cmakedefine HAVE_STRTOLL 1 #cmakedefine HAVE_STRTOQ 1 #cmakedefine HAVE__STRTOI64 1 #cmakedefine PCRE_STATIC 1 #cmakedefine SUPPORT_PCRE8 1 #cmakedefine SUPPORT_PCRE16 1 #cmakedefine SUPPORT_JIT 1 #cmakedefine SUPPORT_PCREGREP_JIT 1 #cmakedefine SUPPORT_UTF 1 #cmakedefine SUPPORT_UCP 1 #cmakedefine EBCDIC 1 #cmakedefine BSR_ANYCRLF 1 #cmakedefine NO_RECURSE 1 #cmakedefine HAVE_LONG_LONG 1 #cmakedefine HAVE_UNSIGNED_LONG_LONG 1 #cmakedefine SUPPORT_LIBBZ2 1 #cmakedefine SUPPORT_LIBZ 1 #cmakedefine SUPPORT_LIBEDIT 1 #cmakedefine SUPPORT_LIBREADLINE 1 #define NEWLINE @NEWLINE@ #define POSIX_MALLOC_THRESHOLD @PCRE_POSIX_MALLOC_THRESHOLD@ #define LINK_SIZE @PCRE_LINK_SIZE@ #define MATCH_LIMIT @PCRE_MATCH_LIMIT@ #define MATCH_LIMIT_RECURSION @PCRE_MATCH_LIMIT_RECURSION@ #define PCREGREP_BUFSIZE @PCREGREP_BUFSIZE@ #define MAX_NAME_SIZE 32 #define MAX_NAME_COUNT 10000 /* end config.h for CMake builds */ pcre-8.31/pcre_stringpiece_unittest.cc0000644000222100022210000000677111473712201015107 00000000000000// Copyright 2003 and onwards Google Inc. // Author: Sanjay Ghemawat #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include // for make_pair #include "pcrecpp.h" #include "pcre_stringpiece.h" // CHECK dies with a fatal error if condition is not true. It is *not* // controlled by NDEBUG, so the check will be executed regardless of // compilation mode. Therefore, it is safe to do things like: // CHECK(fp->Write(x) == 4) #define CHECK(condition) do { \ if (!(condition)) { \ fprintf(stderr, "%s:%d: Check failed: %s\n", \ __FILE__, __LINE__, #condition); \ exit(1); \ } \ } while (0) using pcrecpp::StringPiece; static void CheckSTLComparator() { string s1("foo"); string s2("bar"); string s3("baz"); StringPiece p1(s1); StringPiece p2(s2); StringPiece p3(s3); typedef std::map TestMap; TestMap map; map.insert(std::make_pair(p1, 0)); map.insert(std::make_pair(p2, 1)); map.insert(std::make_pair(p3, 2)); CHECK(map.size() == 3); TestMap::const_iterator iter = map.begin(); CHECK(iter->second == 1); ++iter; CHECK(iter->second == 2); ++iter; CHECK(iter->second == 0); ++iter; CHECK(iter == map.end()); TestMap::iterator new_iter = map.find("zot"); CHECK(new_iter == map.end()); new_iter = map.find("bar"); CHECK(new_iter != map.end()); map.erase(new_iter); CHECK(map.size() == 2); iter = map.begin(); CHECK(iter->second == 2); ++iter; CHECK(iter->second == 0); ++iter; CHECK(iter == map.end()); } static void CheckComparisonOperators() { #define CMP_Y(op, x, y) \ CHECK( (StringPiece((x)) op StringPiece((y)))); \ CHECK( (StringPiece((x)).compare(StringPiece((y))) op 0)) #define CMP_N(op, x, y) \ CHECK(!(StringPiece((x)) op StringPiece((y)))); \ CHECK(!(StringPiece((x)).compare(StringPiece((y))) op 0)) CMP_Y(==, "", ""); CMP_Y(==, "a", "a"); CMP_Y(==, "aa", "aa"); CMP_N(==, "a", ""); CMP_N(==, "", "a"); CMP_N(==, "a", "b"); CMP_N(==, "a", "aa"); CMP_N(==, "aa", "a"); CMP_N(!=, "", ""); CMP_N(!=, "a", "a"); CMP_N(!=, "aa", "aa"); CMP_Y(!=, "a", ""); CMP_Y(!=, "", "a"); CMP_Y(!=, "a", "b"); CMP_Y(!=, "a", "aa"); CMP_Y(!=, "aa", "a"); CMP_Y(<, "a", "b"); CMP_Y(<, "a", "aa"); CMP_Y(<, "aa", "b"); CMP_Y(<, "aa", "bb"); CMP_N(<, "a", "a"); CMP_N(<, "b", "a"); CMP_N(<, "aa", "a"); CMP_N(<, "b", "aa"); CMP_N(<, "bb", "aa"); CMP_Y(<=, "a", "a"); CMP_Y(<=, "a", "b"); CMP_Y(<=, "a", "aa"); CMP_Y(<=, "aa", "b"); CMP_Y(<=, "aa", "bb"); CMP_N(<=, "b", "a"); CMP_N(<=, "aa", "a"); CMP_N(<=, "b", "aa"); CMP_N(<=, "bb", "aa"); CMP_N(>=, "a", "b"); CMP_N(>=, "a", "aa"); CMP_N(>=, "aa", "b"); CMP_N(>=, "aa", "bb"); CMP_Y(>=, "a", "a"); CMP_Y(>=, "b", "a"); CMP_Y(>=, "aa", "a"); CMP_Y(>=, "b", "aa"); CMP_Y(>=, "bb", "aa"); CMP_N(>, "a", "a"); CMP_N(>, "a", "b"); CMP_N(>, "a", "aa"); CMP_N(>, "aa", "b"); CMP_N(>, "aa", "bb"); CMP_Y(>, "b", "a"); CMP_Y(>, "aa", "a"); CMP_Y(>, "b", "aa"); CMP_Y(>, "bb", "aa"); #undef CMP_Y #undef CMP_N } int main(int argc, char** argv) { CheckComparisonOperators(); CheckSTLComparator(); printf("OK\n"); return 0; } pcre-8.31/pcre_scanner.h0000644000222100022210000001471010745131030012113 00000000000000// Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat // // Regular-expression based scanner for parsing an input stream. // // Example 1: parse a sequence of "var = number" entries from input: // // Scanner scanner(input); // string var; // int number; // scanner.SetSkipExpression("\\s+"); // Skip any white space we encounter // while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) { // ...; // } #ifndef _PCRE_SCANNER_H #define _PCRE_SCANNER_H #include #include #include #include #include namespace pcrecpp { class PCRECPP_EXP_DEFN Scanner { public: Scanner(); explicit Scanner(const std::string& input); ~Scanner(); // Return current line number. The returned line-number is // one-based. I.e. it returns 1 + the number of consumed newlines. // // Note: this method may be slow. It may take time proportional to // the size of the input. int LineNumber() const; // Return the byte-offset that the scanner is looking in the // input data; int Offset() const; // Return true iff the start of the remaining input matches "re" bool LookingAt(const RE& re) const; // Return true iff all of the following are true // a. the start of the remaining input matches "re", // b. if any arguments are supplied, matched sub-patterns can be // parsed and stored into the arguments. // If it returns true, it skips over the matched input and any // following input that matches the "skip" regular expression. bool Consume(const RE& re, const Arg& arg0 = RE::no_arg, const Arg& arg1 = RE::no_arg, const Arg& arg2 = RE::no_arg // TODO: Allow more arguments? ); // Set the "skip" regular expression. If after consuming some data, // a prefix of the input matches this RE, it is automatically // skipped. For example, a programming language scanner would use // a skip RE that matches white space and comments. // // scanner.SetSkipExpression("\\s+|//.*|/[*](.|\n)*?[*]/"); // // Skipping repeats as long as it succeeds. We used to let people do // this by writing "(...)*" in the regular expression, but that added // up to lots of recursive calls within the pcre library, so now we // control repetition explicitly via the function call API. // // You can pass NULL for "re" if you do not want any data to be skipped. void Skip(const char* re); // DEPRECATED; does *not* repeat void SetSkipExpression(const char* re); // Temporarily pause "skip"ing. This // Skip("Foo"); code ; DisableSkip(); code; EnableSkip() // is similar to // Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo"); // but avoids creating/deleting new RE objects. void DisableSkip(); // Reenable previously paused skipping. Any prefix of the input // that matches the skip pattern is immediately dropped. void EnableSkip(); /***** Special wrappers around SetSkip() for some common idioms *****/ // Arranges to skip whitespace, C comments, C++ comments. // The overall RE is a disjunction of the following REs: // \\s whitespace // //.*\n C++ comment // /[*](.|\n)*?[*]/ C comment (x*? means minimal repetitions of x) // We get repetition via the semantics of SetSkipExpression, not by using * void SkipCXXComments() { SetSkipExpression("\\s|//.*\n|/[*](?:\n|.)*?[*]/"); } void set_save_comments(bool comments) { save_comments_ = comments; } bool save_comments() { return save_comments_; } // Append to vector ranges the comments found in the // byte range [start,end] (inclusive) of the input data. // Only comments that were extracted entirely within that // range are returned: no range splitting of atomically-extracted // comments is performed. void GetComments(int start, int end, std::vector *ranges); // Append to vector ranges the comments added // since the last time this was called. This // functionality is provided for efficiency when // interleaving scanning with parsing. void GetNextComments(std::vector *ranges); private: std::string data_; // All the input data StringPiece input_; // Unprocessed input RE* skip_; // If non-NULL, RE for skipping input bool should_skip_; // If true, use skip_ bool skip_repeat_; // If true, repeat skip_ as long as it works bool save_comments_; // If true, aggregate the skip expression // the skipped comments // TODO: later consider requiring that the StringPieces be added // in order by their start position std::vector *comments_; // the offset into comments_ that has been returned by GetNextComments int comments_offset_; // helper function to consume *skip_ and honour // save_comments_ void ConsumeSkip(); }; } // namespace pcrecpp #endif /* _PCRE_SCANNER_H */ pcre-8.31/ChangeLog0000644000222100022210000070646211775523724011111 00000000000000ChangeLog for PCRE ------------------ Version 8.31 06-July-2012 ------------------------- 1. Fixing a wrong JIT test case and some compiler warnings. 2. Removed a bashism from the RunTest script. 3. Add a cast to pcre_exec.c to fix the warning "unary minus operator applied to unsigned type, result still unsigned" that was given by an MS compiler on encountering the code "-sizeof(xxx)". 4. Partial matching support is added to the JIT compiler. 5. Fixed several bugs concerned with partial matching of items that consist of more than one character: (a) /^(..)\1/ did not partially match "aba" because checking references was done on an "all or nothing" basis. This also applied to repeated references. (b) \R did not give a hard partial match if \r was found at the end of the subject. (c) \X did not give a hard partial match after matching one or more characters at the end of the subject. (d) When newline was set to CRLF, a pattern such as /a$/ did not recognize a partial match for the string "\r". (e) When newline was set to CRLF, the metacharacter "." did not recognize a partial match for a CR character at the end of the subject string. 6. If JIT is requested using /S++ or -s++ (instead of just /S+ or -s+) when running pcretest, the text "(JIT)" added to the output whenever JIT is actually used to run the match. 7. Individual JIT compile options can be set in pcretest by following -s+[+] or /S+[+] with a digit between 1 and 7. 8. OP_NOT now supports any UTF character not just single-byte ones. 9. (*MARK) control verb is now supported by the JIT compiler. 10. The command "./RunTest list" lists the available tests without actually running any of them. (Because I keep forgetting what they all are.) 11. Add PCRE_INFO_MAXLOOKBEHIND. 12. Applied a (slightly modified) user-supplied patch that improves performance when the heap is used for recursion (compiled with --disable-stack-for- recursion). Instead of malloc and free for each heap frame each time a logical recursion happens, frames are retained on a chain and re-used where possible. This sometimes gives as much as 30% improvement. 13. As documented, (*COMMIT) is now confined to within a recursive subpattern call. 14. As documented, (*COMMIT) is now confined to within a positive assertion. 15. It is now possible to link pcretest with libedit as an alternative to libreadline. 16. (*COMMIT) control verb is now supported by the JIT compiler. 17. The Unicode data tables have been updated to Unicode 6.1.0. 18. Added --file-list option to pcregrep. 19. Added binary file support to pcregrep, including the -a, --binary-files, -I, and --text options. 20. The madvise function is renamed for posix_madvise for QNX compatibility reasons. Fixed by Giuseppe D'Angelo. 21. Fixed a bug for backward assertions with REVERSE 0 in the JIT compiler. 22. Changed the option for creating symbolic links for 16-bit man pages from -s to -sf so that re-installing does not cause issues. 23. Support PCRE_NO_START_OPTIMIZE in JIT as (*MARK) support requires it. 24. Fixed a very old bug in pcretest that caused errors with restarted DFA matches in certain environments (the workspace was not being correctly retained). Also added to pcre_dfa_exec() a simple plausibility check on some of the workspace data at the beginning of a restart. 25. \s*\R was auto-possessifying the \s* when it should not, whereas \S*\R was not doing so when it should - probably a typo introduced by SVN 528 (change 8.10/14). 26. When PCRE_UCP was not set, \w+\x{c4} was incorrectly auto-possessifying the \w+ when the character tables indicated that \x{c4} was a word character. There were several related cases, all because the tests for doing a table lookup were testing for characters less than 127 instead of 255. 27. If a pattern contains capturing parentheses that are not used in a match, their slots in the ovector are set to -1. For those that are higher than any matched groups, this happens at the end of processing. In the case when there were back references that the ovector was too small to contain (causing temporary malloc'd memory to be used during matching), and the highest capturing number was not used, memory off the end of the ovector was incorrectly being set to -1. (It was using the size of the temporary memory instead of the true size.) 28. To catch bugs like 27 using valgrind, when pcretest is asked to specify an ovector size, it uses memory at the end of the block that it has got. 29. Check for an overlong MARK name and give an error at compile time. The limit is 255 for the 8-bit library and 65535 for the 16-bit library. 30. JIT compiler update. 31. JIT is now supported on jailbroken iOS devices. Thanks for Ruiger Rill for the patch. 32. Put spaces around SLJIT_PRINT_D in the JIT compiler. Required by CXX11. 33. Variable renamings in the PCRE-JIT compiler. No functionality change. 34. Fixed typos in pcregrep: in two places there was SUPPORT_LIBZ2 instead of SUPPORT_LIBBZ2. This caused a build problem when bzip2 but not gzip (zlib) was enabled. 35. Improve JIT code generation for greedy plus quantifier. 36. When /((?:a?)*)*c/ or /((?>a?)*)*c/ was matched against "aac", it set group 1 to "aa" instead of to an empty string. The bug affected repeated groups that could potentially match an empty string. 37. Optimizing single character iterators in JIT. 38. Wide characters specified with \uxxxx in JavaScript mode are now subject to the same checks as \x{...} characters in non-JavaScript mode. Specifically, codepoints that are too big for the mode are faulted, and in a UTF mode, disallowed codepoints are also faulted. 39. If PCRE was compiled with UTF support, in three places in the DFA matcher there was code that should only have been obeyed in UTF mode, but was being obeyed unconditionally. In 8-bit mode this could cause incorrect processing when bytes with values greater than 127 were present. In 16-bit mode the bug would be provoked by values in the range 0xfc00 to 0xdc00. In both cases the values are those that cannot be the first data item in a UTF character. The three items that might have provoked this were recursions, possessively repeated groups, and atomic groups. 40. Ensure that libpcre is explicitly listed in the link commands for pcretest and pcregrep, because some OS require shared objects to be explicitly passed to ld, causing the link step to fail if they are not. 41. There were two incorrect #ifdefs in pcre_study.c, meaning that, in 16-bit mode, patterns that started with \h* or \R* might be incorrectly matched. Version 8.30 04-February-2012 ----------------------------- 1. Renamed "isnumber" as "is_a_number" because in some Mac environments this name is defined in ctype.h. 2. Fixed a bug in fixed-length calculation for lookbehinds that would show up only in quite long subpatterns. 3. Removed the function pcre_info(), which has been obsolete and deprecated since it was replaced by pcre_fullinfo() in February 2000. 4. For a non-anchored pattern, if (*SKIP) was given with a name that did not match a (*MARK), and the match failed at the start of the subject, a reference to memory before the start of the subject could occur. This bug was introduced by fix 17 of release 8.21. 5. A reference to an unset group with zero minimum repetition was giving totally wrong answers (in non-JavaScript-compatibility mode). For example, /(another)?(\1?)test/ matched against "hello world test". This bug was introduced in release 8.13. 6. Add support for 16-bit character strings (a large amount of work involving many changes and refactorings). 7. RunGrepTest failed on msys because \r\n was replaced by whitespace when the command "pattern=`printf 'xxx\r\njkl'`" was run. The pattern is now taken from a file. 8. Ovector size of 2 is also supported by JIT based pcre_exec (the ovector size rounding is not applied in this particular case). 9. The invalid Unicode surrogate codepoints U+D800 to U+DFFF are now rejected if they appear, or are escaped, in patterns. 10. Get rid of a number of -Wunused-but-set-variable warnings. 11. The pattern /(?=(*:x))(q|)/ matches an empty string, and returns the mark "x". The similar pattern /(?=(*:x))((*:y)q|)/ did not return a mark at all. Oddly, Perl behaves the same way. PCRE has been fixed so that this pattern also returns the mark "x". This bug applied to capturing parentheses, non-capturing parentheses, and atomic parentheses. It also applied to some assertions. 12. Stephen Kelly's patch to CMakeLists.txt allows it to parse the version information out of configure.ac instead of relying on pcre.h.generic, which is not stored in the repository. 13. Applied Dmitry V. Levin's patch for a more portable method for linking with -lreadline. 14. ZH added PCRE_CONFIG_JITTARGET; added its output to pcretest -C. 15. Applied Graycode's patch to put the top-level frame on the stack rather than the heap when not using the stack for recursion. This gives a performance improvement in many cases when recursion is not deep. 16. Experimental code added to "pcretest -C" to output the stack frame size. Version 8.21 12-Dec-2011 ------------------------ 1. Updating the JIT compiler. 2. JIT compiler now supports OP_NCREF, OP_RREF and OP_NRREF. New test cases are added as well. 3. Fix cache-flush issue on PowerPC (It is still an experimental JIT port). PCRE_EXTRA_TABLES is not suported by JIT, and should be checked before calling _pcre_jit_exec. Some extra comments are added. 4. (*MARK) settings inside atomic groups that do not contain any capturing parentheses, for example, (?>a(*:m)), were not being passed out. This bug was introduced by change 18 for 8.20. 5. Supporting of \x, \U and \u in JavaScript compatibility mode based on the ECMA-262 standard. 6. Lookbehinds such as (?<=a{2}b) that contained a fixed repetition were erroneously being rejected as "not fixed length" if PCRE_CASELESS was set. This bug was probably introduced by change 9 of 8.13. 7. While fixing 6 above, I noticed that a number of other items were being incorrectly rejected as "not fixed length". This arose partly because newer opcodes had not been added to the fixed-length checking code. I have (a) corrected the bug and added tests for these items, and (b) arranged for an error to occur if an unknown opcode is encountered while checking for fixed length instead of just assuming "not fixed length". The items that were rejected were: (*ACCEPT), (*COMMIT), (*FAIL), (*MARK), (*PRUNE), (*SKIP), (*THEN), \h, \H, \v, \V, and single character negative classes with fixed repetitions, e.g. [^a]{3}, with and without PCRE_CASELESS. 8. A possessively repeated conditional subpattern such as (?(?=c)c|d)++ was being incorrectly compiled and would have given unpredicatble results. 9. A possessively repeated subpattern with minimum repeat count greater than one behaved incorrectly. For example, (A){2,}+ behaved as if it was (A)(A)++ which meant that, after a subsequent mismatch, backtracking into the first (A) could occur when it should not. 10. Add a cast and remove a redundant test from the code. 11. JIT should use pcre_malloc/pcre_free for allocation. 12. Updated pcre-config so that it no longer shows -L/usr/lib, which seems best practice nowadays, and helps with cross-compiling. (If the exec_prefix is anything other than /usr, -L is still shown). 13. In non-UTF-8 mode, \C is now supported in lookbehinds and DFA matching. 14. Perl does not support \N without a following name in a [] class; PCRE now also gives an error. 15. If a forward reference was repeated with an upper limit of around 2000, it caused the error "internal error: overran compiling workspace". The maximum number of forward references (including repeats) was limited by the internal workspace, and dependent on the LINK_SIZE. The code has been rewritten so that the workspace expands (via pcre_malloc) if necessary, and the default depends on LINK_SIZE. There is a new upper limit (for safety) of around 200,000 forward references. While doing this, I also speeded up the filling in of repeated forward references. 16. A repeated forward reference in a pattern such as (a)(?2){2}(.) was incorrectly expecting the subject to contain another "a" after the start. 17. When (*SKIP:name) is activated without a corresponding (*MARK:name) earlier in the match, the SKIP should be ignored. This was not happening; instead the SKIP was being treated as NOMATCH. For patterns such as /A(*MARK:A)A+(*SKIP:B)Z|AAC/ this meant that the AAC branch was never tested. 18. The behaviour of (*MARK), (*PRUNE), and (*THEN) has been reworked and is now much more compatible with Perl, in particular in cases where the result is a non-match for a non-anchored pattern. For example, if /b(*:m)f|a(*:n)w/ is matched against "abc", the non-match returns the name "m", where previously it did not return a name. A side effect of this change is that for partial matches, the last encountered mark name is returned, as for non matches. A number of tests that were previously not Perl-compatible have been moved into the Perl-compatible test files. The refactoring has had the pleasing side effect of removing one argument from the match() function, thus reducing its stack requirements. 19. If the /S+ option was used in pcretest to study a pattern using JIT, subsequent uses of /S (without +) incorrectly behaved like /S+. 21. Retrieve executable code size support for the JIT compiler and fixing some warnings. 22. A caseless match of a UTF-8 character whose other case uses fewer bytes did not work when the shorter character appeared right at the end of the subject string. 23. Added some (int) casts to non-JIT modules to reduce warnings on 64-bit systems. 24. Added PCRE_INFO_JITSIZE to pass on the value from (21) above, and also output it when the /M option is used in pcretest. 25. The CheckMan script was not being included in the distribution. Also, added an explicit "perl" to run Perl scripts from the PrepareRelease script because this is reportedly needed in Windows. 26. If study data was being save in a file and studying had not found a set of "starts with" bytes for the pattern, the data written to the file (though never used) was taken from uninitialized memory and so caused valgrind to complain. 27. Updated RunTest.bat as provided by Sheri Pierce. 28. Fixed a possible uninitialized memory bug in pcre_jit_compile.c. 29. Computation of memory usage for the table of capturing group names was giving an unnecessarily large value. Version 8.20 21-Oct-2011 ------------------------ 1. Change 37 of 8.13 broke patterns like [:a]...[b:] because it thought it had a POSIX class. After further experiments with Perl, which convinced me that Perl has bugs and confusions, a closing square bracket is no longer allowed in a POSIX name. This bug also affected patterns with classes that started with full stops. 2. If a pattern such as /(a)b|ac/ is matched against "ac", there is no captured substring, but while checking the failing first alternative, substring 1 is temporarily captured. If the output vector supplied to pcre_exec() was not big enough for this capture, the yield of the function was still zero ("insufficient space for captured substrings"). This cannot be totally fixed without adding another stack variable, which seems a lot of expense for a edge case. However, I have improved the situation in cases such as /(a)(b)x|abc/ matched against "abc", where the return code indicates that fewer than the maximum number of slots in the ovector have been set. 3. Related to (2) above: when there are more back references in a pattern than slots in the output vector, pcre_exec() uses temporary memory during matching, and copies in the captures as far as possible afterwards. It was using the entire output vector, but this conflicts with the specification that only 2/3 is used for passing back captured substrings. Now it uses only the first 2/3, for compatibility. This is, of course, another edge case. 4. Zoltan Herczeg's just-in-time compiler support has been integrated into the main code base, and can be used by building with --enable-jit. When this is done, pcregrep automatically uses it unless --disable-pcregrep-jit or the runtime --no-jit option is given. 5. When the number of matches in a pcre_dfa_exec() run exactly filled the ovector, the return from the function was zero, implying that there were other matches that did not fit. The correct "exactly full" value is now returned. 6. If a subpattern that was called recursively or as a subroutine contained (*PRUNE) or any other control that caused it to give a non-standard return, invalid errors such as "Error -26 (nested recursion at the same subject position)" or even infinite loops could occur. 7. If a pattern such as /a(*SKIP)c|b(*ACCEPT)|/ was studied, it stopped computing the minimum length on reaching *ACCEPT, and so ended up with the wrong value of 1 rather than 0. Further investigation indicates that computing a minimum subject length in the presence of *ACCEPT is difficult (think back references, subroutine calls), and so I have changed the code so that no minimum is registered for a pattern that contains *ACCEPT. 8. If (*THEN) was present in the first (true) branch of a conditional group, it was not handled as intended. [But see 16 below.] 9. Replaced RunTest.bat and CMakeLists.txt with improved versions provided by Sheri Pierce. 10. A pathological pattern such as /(*ACCEPT)a/ was miscompiled, thinking that the first byte in a match must be "a". 11. Change 17 for 8.13 increased the recursion depth for patterns like /a(?:.)*?a/ drastically. I've improved things by remembering whether a pattern contains any instances of (*THEN). If it does not, the old optimizations are restored. It would be nice to do this on a per-group basis, but at the moment that is not feasible. 12. In some environments, the output of pcretest -C is CRLF terminated. This broke RunTest's code that checks for the link size. A single white space character after the value is now allowed for. 13. RunTest now checks for the "fr" locale as well as for "fr_FR" and "french". For "fr", it uses the Windows-specific input and output files. 14. If (*THEN) appeared in a group that was called recursively or as a subroutine, it did not work as intended. [But see next item.] 15. Consider the pattern /A (B(*THEN)C) | D/ where A, B, C, and D are complex pattern fragments (but not containing any | characters). If A and B are matched, but there is a failure in C so that it backtracks to (*THEN), PCRE was behaving differently to Perl. PCRE backtracked into A, but Perl goes to D. In other words, Perl considers parentheses that do not contain any | characters to be part of a surrounding alternative, whereas PCRE was treading (B(*THEN)C) the same as (B(*THEN)C|(*FAIL)) -- which Perl handles differently. PCRE now behaves in the same way as Perl, except in the case of subroutine/recursion calls such as (?1) which have in any case always been different (but PCRE had them first :-). 16. Related to 15 above: Perl does not treat the | in a conditional group as creating alternatives. Such a group is treated in the same way as an ordinary group without any | characters when processing (*THEN). PCRE has been changed to match Perl's behaviour. 17. If a user had set PCREGREP_COLO(U)R to something other than 1:31, the RunGrepTest script failed. 18. Change 22 for version 13 caused atomic groups to use more stack. This is inevitable for groups that contain captures, but it can lead to a lot of stack use in large patterns. The old behaviour has been restored for atomic groups that do not contain any capturing parentheses. 19. If the PCRE_NO_START_OPTIMIZE option was set for pcre_compile(), it did not suppress the check for a minimum subject length at run time. (If it was given to pcre_exec() or pcre_dfa_exec() it did work.) 20. Fixed an ASCII-dependent infelicity in pcretest that would have made it fail to work when decoding hex characters in data strings in EBCDIC environments. 21. It appears that in at least one Mac OS environment, the isxdigit() function is implemented as a macro that evaluates to its argument more than once, contravening the C 90 Standard (I haven't checked a later standard). There was an instance in pcretest which caused it to go wrong when processing \x{...} escapes in subject strings. The has been rewritten to avoid using things like p++ in the argument of isxdigit(). Version 8.13 16-Aug-2011 ------------------------ 1. The Unicode data tables have been updated to Unicode 6.0.0. 2. Two minor typos in pcre_internal.h have been fixed. 3. Added #include to pcre_scanner_unittest.cc, pcrecpp.cc, and pcrecpp_unittest.cc. They are needed for strcmp(), memset(), and strchr() in some environments (e.g. Solaris 10/SPARC using Sun Studio 12U2). 4. There were a number of related bugs in the code for matching backrefences caselessly in UTF-8 mode when codes for the characters concerned were different numbers of bytes. For example, U+023A and U+2C65 are an upper and lower case pair, using 2 and 3 bytes, respectively. The main bugs were: (a) A reference to 3 copies of a 2-byte code matched only 2 of a 3-byte code. (b) A reference to 2 copies of a 3-byte code would not match 2 of a 2-byte code at the end of the subject (it thought there wasn't enough data left). 5. Comprehensive information about what went wrong is now returned by pcre_exec() and pcre_dfa_exec() when the UTF-8 string check fails, as long as the output vector has at least 2 elements. The offset of the start of the failing character and a reason code are placed in the vector. 6. When the UTF-8 string check fails for pcre_compile(), the offset that is now returned is for the first byte of the failing character, instead of the last byte inspected. This is an incompatible change, but I hope it is small enough not to be a problem. It makes the returned offset consistent with pcre_exec() and pcre_dfa_exec(). 7. pcretest now gives a text phrase as well as the error number when pcre_exec() or pcre_dfa_exec() fails; if the error is a UTF-8 check failure, the offset and reason code are output. 8. When \R was used with a maximizing quantifier it failed to skip backwards over a \r\n pair if the subsequent match failed. Instead, it just skipped back over a single character (\n). This seems wrong (because it treated the two characters as a single entity when going forwards), conflicts with the documentation that \R is equivalent to (?>\r\n|\n|...etc), and makes the behaviour of \R* different to (\R)*, which also seems wrong. The behaviour has been changed. 9. Some internal refactoring has changed the processing so that the handling of the PCRE_CASELESS and PCRE_MULTILINE options is done entirely at compile time (the PCRE_DOTALL option was changed this way some time ago: version 7.7 change 16). This has made it possible to abolish the OP_OPT op code, which was always a bit of a fudge. It also means that there is one less argument for the match() function, which reduces its stack requirements slightly. This change also fixes an incompatibility with Perl: the pattern (?i:([^b]))(?1) should not match "ab", but previously PCRE gave a match. 10. More internal refactoring has drastically reduced the number of recursive calls to match() for possessively repeated groups such as (abc)++ when using pcre_exec(). 11. While implementing 10, a number of bugs in the handling of groups were discovered and fixed: (?<=(a)+) was not diagnosed as invalid (non-fixed-length lookbehind). (a|)*(?1) gave a compile-time internal error. ((a|)+)+ did not notice that the outer group could match an empty string. (^a|^)+ was not marked as anchored. (.*a|.*)+ was not marked as matching at start or after a newline. 12. Yet more internal refactoring has removed another argument from the match() function. Special calls to this function are now indicated by setting a value in a variable in the "match data" data block. 13. Be more explicit in pcre_study() instead of relying on "default" for opcodes that mean there is no starting character; this means that when new ones are added and accidentally left out of pcre_study(), testing should pick them up. 14. The -s option of pcretest has been documented for ages as being an old synonym of -m (show memory usage). I have changed it to mean "force study for every regex", that is, assume /S for every regex. This is similar to -i and -d etc. It's slightly incompatible, but I'm hoping nobody is still using it. It makes it easier to run collections of tests with and without study enabled, and thereby test pcre_study() more easily. All the standard tests are now run with and without -s (but some patterns can be marked as "never study" - see 20 below). 15. When (*ACCEPT) was used in a subpattern that was called recursively, the restoration of the capturing data to the outer values was not happening correctly. 16. If a recursively called subpattern ended with (*ACCEPT) and matched an empty string, and PCRE_NOTEMPTY was set, pcre_exec() thought the whole pattern had matched an empty string, and so incorrectly returned a no match. 17. There was optimizing code for the last branch of non-capturing parentheses, and also for the obeyed branch of a conditional subexpression, which used tail recursion to cut down on stack usage. Unfortunately, now that there is the possibility of (*THEN) occurring in these branches, tail recursion is no longer possible because the return has to be checked for (*THEN). These two optimizations have therefore been removed. [But see 8.20/11 above.] 18. If a pattern containing \R was studied, it was assumed that \R always matched two bytes, thus causing the minimum subject length to be incorrectly computed because \R can also match just one byte. 19. If a pattern containing (*ACCEPT) was studied, the minimum subject length was incorrectly computed. 20. If /S is present twice on a test pattern in pcretest input, it now *disables* studying, thereby overriding the use of -s on the command line (see 14 above). This is necessary for one or two tests to keep the output identical in both cases. 21. When (*ACCEPT) was used in an assertion that matched an empty string and PCRE_NOTEMPTY was set, PCRE applied the non-empty test to the assertion. 22. When an atomic group that contained a capturing parenthesis was successfully matched, but the branch in which it appeared failed, the capturing was not being forgotten if a higher numbered group was later captured. For example, /(?>(a))b|(a)c/ when matching "ac" set capturing group 1 to "a", when in fact it should be unset. This applied to multi- branched capturing and non-capturing groups, repeated or not, and also to positive assertions (capturing in negative assertions does not happen in PCRE) and also to nested atomic groups. 23. Add the ++ qualifier feature to pcretest, to show the remainder of the subject after a captured substring, to make it easier to tell which of a number of identical substrings has been captured. 24. The way atomic groups are processed by pcre_exec() has been changed so that if they are repeated, backtracking one repetition now resets captured values correctly. For example, if ((?>(a+)b)+aabab) is matched against "aaaabaaabaabab" the value of captured group 2 is now correctly recorded as "aaa". Previously, it would have been "a". As part of this code refactoring, the way recursive calls are handled has also been changed. 25. If an assertion condition captured any substrings, they were not passed back unless some other capturing happened later. For example, if (?(?=(a))a) was matched against "a", no capturing was returned. 26. When studying a pattern that contained subroutine calls or assertions, the code for finding the minimum length of a possible match was handling direct recursions such as (xxx(?1)|yyy) but not mutual recursions (where group 1 called group 2 while simultaneously a separate group 2 called group 1). A stack overflow occurred in this case. I have fixed this by limiting the recursion depth to 10. 27. Updated RunTest.bat in the distribution to the version supplied by Tom Fortmann. This supports explicit test numbers on the command line, and has argument validation and error reporting. 28. An instance of \X with an unlimited repeat could fail if at any point the first character it looked at was a mark character. 29. Some minor code refactoring concerning Unicode properties and scripts should reduce the stack requirement of match() slightly. 30. Added the '=' option to pcretest to check the setting of unused capturing slots at the end of the pattern, which are documented as being -1, but are not included in the return count. 31. If \k was not followed by a braced, angle-bracketed, or quoted name, PCRE compiled something random. Now it gives a compile-time error (as does Perl). 32. A *MARK encountered during the processing of a positive assertion is now recorded and passed back (compatible with Perl). 33. If --only-matching or --colour was set on a pcregrep call whose pattern had alternative anchored branches, the search for a second match in a line was done as if at the line start. Thus, for example, /^01|^02/ incorrectly matched the line "0102" twice. The same bug affected patterns that started with a backwards assertion. For example /\b01|\b02/ also matched "0102" twice. 34. Previously, PCRE did not allow quantification of assertions. However, Perl does, and because of capturing effects, quantifying parenthesized assertions may at times be useful. Quantifiers are now allowed for parenthesized assertions. 35. A minor code tidy in pcre_compile() when checking options for \R usage. 36. \g was being checked for fancy things in a character class, when it should just be a literal "g". 37. PCRE was rejecting [:a[:digit:]] whereas Perl was not. It seems that the appearance of a nested POSIX class supersedes an apparent external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or a digit. Also, unescaped square brackets may also appear as part of class names. For example, [:a[:abc]b:] gives unknown class "[:abc]b:]". PCRE now behaves more like Perl. (But see 8.20/1 above.) 38. PCRE was giving an error for \N with a braced quantifier such as {1,} (this was because it thought it was \N{name}, which is not supported). 39. Add minix to OS list not supporting the -S option in pcretest. 40. PCRE tries to detect cases of infinite recursion at compile time, but it cannot analyze patterns in sufficient detail to catch mutual recursions such as ((?1))((?2)). There is now a runtime test that gives an error if a subgroup is called recursively as a subpattern for a second time at the same position in the subject string. In previous releases this might have been caught by the recursion limit, or it might have run out of stack. 41. A pattern such as /(?(R)a+|(?R)b)/ is quite safe, as the recursion can happen only once. PCRE was, however incorrectly giving a compile time error "recursive call could loop indefinitely" because it cannot analyze the pattern in sufficient detail. The compile time test no longer happens when PCRE is compiling a conditional subpattern, but actual runaway loops are now caught at runtime (see 40 above). 42. It seems that Perl allows any characters other than a closing parenthesis to be part of the NAME in (*MARK:NAME) and other backtracking verbs. PCRE has been changed to be the same. 43. Updated configure.ac to put in more quoting round AC_LANG_PROGRAM etc. so as not to get warnings when autogen.sh is called. Also changed AC_PROG_LIBTOOL (deprecated) to LT_INIT (the current macro). 44. To help people who use pcregrep to scan files containing exceedingly long lines, the following changes have been made: (a) The default value of the buffer size parameter has been increased from 8K to 20K. (The actual buffer used is three times this size.) (b) The default can be changed by ./configure --with-pcregrep-bufsize when PCRE is built. (c) A --buffer-size=n option has been added to pcregrep, to allow the size to be set at run time. (d) Numerical values in pcregrep options can be followed by K or M, for example --buffer-size=50K. (e) If a line being scanned overflows pcregrep's buffer, an error is now given and the return code is set to 2. 45. Add a pointer to the latest mark to the callout data block. 46. The pattern /.(*F)/, when applied to "abc" with PCRE_PARTIAL_HARD, gave a partial match of an empty string instead of no match. This was specific to the use of ".". 47. The pattern /f.*/8s, when applied to "for" with PCRE_PARTIAL_HARD, gave a complete match instead of a partial match. This bug was dependent on both the PCRE_UTF8 and PCRE_DOTALL options being set. 48. For a pattern such as /\babc|\bdef/ pcre_study() was failing to set up the starting byte set, because \b was not being ignored. Version 8.12 15-Jan-2011 ------------------------ 1. Fixed some typos in the markup of the man pages, and wrote a script that checks for such things as part of the documentation building process. 2. On a big-endian 64-bit system, pcregrep did not correctly process the --match-limit and --recursion-limit options (added for 8.11). In particular, this made one of the standard tests fail. (The integer value went into the wrong half of a long int.) 3. If the --colour option was given to pcregrep with -v (invert match), it did strange things, either producing crazy output, or crashing. It should, of course, ignore a request for colour when reporting lines that do not match. 4. Another pcregrep bug caused similar problems if --colour was specified with -M (multiline) and the pattern match finished with a line ending. 5. In pcregrep, when a pattern that ended with a literal newline sequence was matched in multiline mode, the following line was shown as part of the match. This seems wrong, so I have changed it. 6. Another pcregrep bug in multiline mode, when --colour was specified, caused the check for further matches in the same line (so they could be coloured) to overrun the end of the current line. If another match was found, it was incorrectly shown (and then shown again when found in the next line). 7. If pcregrep was compiled under Windows, there was a reference to the function pcregrep_exit() before it was defined. I am assuming this was the cause of the "error C2371: 'pcregrep_exit' : redefinition;" that was reported by a user. I've moved the definition above the reference. Version 8.11 10-Dec-2010 ------------------------ 1. (*THEN) was not working properly if there were untried alternatives prior to it in the current branch. For example, in ((a|b)(*THEN)(*F)|c..) it backtracked to try for "b" instead of moving to the next alternative branch at the same level (in this case, to look for "c"). The Perl documentation is clear that when (*THEN) is backtracked onto, it goes to the "next alternative in the innermost enclosing group". 2. (*COMMIT) was not overriding (*THEN), as it does in Perl. In a pattern such as (A(*COMMIT)B(*THEN)C|D) any failure after matching A should result in overall failure. Similarly, (*COMMIT) now overrides (*PRUNE) and (*SKIP), (*SKIP) overrides (*PRUNE) and (*THEN), and (*PRUNE) overrides (*THEN). 3. If \s appeared in a character class, it removed the VT character from the class, even if it had been included by some previous item, for example in [\x00-\xff\s]. (This was a bug related to the fact that VT is not part of \s, but is part of the POSIX "space" class.) 4. A partial match never returns an empty string (because you can always match an empty string at the end of the subject); however the checking for an empty string was starting at the "start of match" point. This has been changed to the "earliest inspected character" point, because the returned data for a partial match starts at this character. This means that, for example, /(?<=abc)def/ gives a partial match for the subject "abc" (previously it gave "no match"). 5. Changes have been made to the way PCRE_PARTIAL_HARD affects the matching of $, \z, \Z, \b, and \B. If the match point is at the end of the string, previously a full match would be given. However, setting PCRE_PARTIAL_HARD has an implication that the given string is incomplete (because a partial match is preferred over a full match). For this reason, these items now give a partial match in this situation. [Aside: previously, the one case /t\b/ matched against "cat" with PCRE_PARTIAL_HARD set did return a partial match rather than a full match, which was wrong by the old rules, but is now correct.] 6. There was a bug in the handling of #-introduced comments, recognized when PCRE_EXTENDED is set, when PCRE_NEWLINE_ANY and PCRE_UTF8 were also set. If a UTF-8 multi-byte character included the byte 0x85 (e.g. +U0445, whose UTF-8 encoding is 0xd1,0x85), this was misinterpreted as a newline when scanning for the end of the comment. (*Character* 0x85 is an "any" newline, but *byte* 0x85 is not, in UTF-8 mode). This bug was present in several places in pcre_compile(). 7. Related to (6) above, when pcre_compile() was skipping #-introduced comments when looking ahead for named forward references to subpatterns, the only newline sequence it recognized was NL. It now handles newlines according to the set newline convention. 8. SunOS4 doesn't have strerror() or strtoul(); pcregrep dealt with the former, but used strtoul(), whereas pcretest avoided strtoul() but did not cater for a lack of strerror(). These oversights have been fixed. 9. Added --match-limit and --recursion-limit to pcregrep. 10. Added two casts needed to build with Visual Studio when NO_RECURSE is set. 11. When the -o option was used, pcregrep was setting a return code of 1, even when matches were found, and --line-buffered was not being honoured. 12. Added an optional parentheses number to the -o and --only-matching options of pcregrep. 13. Imitating Perl's /g action for multiple matches is tricky when the pattern can match an empty string. The code to do it in pcretest and pcredemo needed fixing: (a) When the newline convention was "crlf", pcretest got it wrong, skipping only one byte after an empty string match just before CRLF (this case just got forgotten; "any" and "anycrlf" were OK). (b) The pcretest code also had a bug, causing it to loop forever in UTF-8 mode when an empty string match preceded an ASCII character followed by a non-ASCII character. (The code for advancing by one character rather than one byte was nonsense.) (c) The pcredemo.c sample program did not have any code at all to handle the cases when CRLF is a valid newline sequence. 14. Neither pcre_exec() nor pcre_dfa_exec() was checking that the value given as a starting offset was within the subject string. There is now a new error, PCRE_ERROR_BADOFFSET, which is returned if the starting offset is negative or greater than the length of the string. In order to test this, pcretest is extended to allow the setting of negative starting offsets. 15. In both pcre_exec() and pcre_dfa_exec() the code for checking that the starting offset points to the beginning of a UTF-8 character was unnecessarily clumsy. I tidied it up. 16. Added PCRE_ERROR_SHORTUTF8 to make it possible to distinguish between a bad UTF-8 sequence and one that is incomplete when using PCRE_PARTIAL_HARD. 17. Nobody had reported that the --include_dir option, which was added in release 7.7 should have been called --include-dir (hyphen, not underscore) for compatibility with GNU grep. I have changed it to --include-dir, but left --include_dir as an undocumented synonym, and the same for --exclude-dir, though that is not available in GNU grep, at least as of release 2.5.4. 18. At a user's suggestion, the macros GETCHAR and friends (which pick up UTF-8 characters from a string of bytes) have been redefined so as not to use loops, in order to improve performance in some environments. At the same time, I abstracted some of the common code into auxiliary macros to save repetition (this should not affect the compiled code). 19. If \c was followed by a multibyte UTF-8 character, bad things happened. A compile-time error is now given if \c is not followed by an ASCII character, that is, a byte less than 128. (In EBCDIC mode, the code is different, and any byte value is allowed.) 20. Recognize (*NO_START_OPT) at the start of a pattern to set the PCRE_NO_ START_OPTIMIZE option, which is now allowed at compile time - but just passed through to pcre_exec() or pcre_dfa_exec(). This makes it available to pcregrep and other applications that have no direct access to PCRE options. The new /Y option in pcretest sets this option when calling pcre_compile(). 21. Change 18 of release 8.01 broke the use of named subpatterns for recursive back references. Groups containing recursive back references were forced to be atomic by that change, but in the case of named groups, the amount of memory required was incorrectly computed, leading to "Failed: internal error: code overflow". This has been fixed. 22. Some patches to pcre_stringpiece.h, pcre_stringpiece_unittest.cc, and pcretest.c, to avoid build problems in some Borland environments. Version 8.10 25-Jun-2010 ------------------------ 1. Added support for (*MARK:ARG) and for ARG additions to PRUNE, SKIP, and THEN. 2. (*ACCEPT) was not working when inside an atomic group. 3. Inside a character class, \B is treated as a literal by default, but faulted if PCRE_EXTRA is set. This mimics Perl's behaviour (the -w option causes the error). The code is unchanged, but I tidied the documentation. 4. Inside a character class, PCRE always treated \R and \X as literals, whereas Perl faults them if its -w option is set. I have changed PCRE so that it faults them when PCRE_EXTRA is set. 5. Added support for \N, which always matches any character other than newline. (It is the same as "." when PCRE_DOTALL is not set.) 6. When compiling pcregrep with newer versions of gcc which may have FORTIFY_SOURCE set, several warnings "ignoring return value of 'fwrite', declared with attribute warn_unused_result" were given. Just casting the result to (void) does not stop the warnings; a more elaborate fudge is needed. I've used a macro to implement this. 7. Minor change to pcretest.c to avoid a compiler warning. 8. Added four artifical Unicode properties to help with an option to make \s etc use properties (see next item). The new properties are: Xan (alphanumeric), Xsp (Perl space), Xps (POSIX space), and Xwd (word). 9. Added PCRE_UCP to make \b, \d, \s, \w, and certain POSIX character classes use Unicode properties. (*UCP) at the start of a pattern can be used to set this option. Modified pcretest to add /W to test this facility. Added REG_UCP to make it available via the POSIX interface. 10. Added --line-buffered to pcregrep. 11. In UTF-8 mode, if a pattern that was compiled with PCRE_CASELESS was studied, and the match started with a letter with a code point greater than 127 whose first byte was different to the first byte of the other case of the letter, the other case of this starting letter was not recognized (#976). 12. If a pattern that was studied started with a repeated Unicode property test, for example, \p{Nd}+, there was the theoretical possibility of setting up an incorrect bitmap of starting bytes, but fortunately it could not have actually happened in practice until change 8 above was made (it added property types that matched character-matching opcodes). 13. pcre_study() now recognizes \h, \v, and \R when constructing a bit map of possible starting bytes for non-anchored patterns. 14. Extended the "auto-possessify" feature of pcre_compile(). It now recognizes \R, and also a number of cases that involve Unicode properties, both explicit and implicit when PCRE_UCP is set. 15. If a repeated Unicode property match (e.g. \p{Lu}*) was used with non-UTF-8 input, it could crash or give wrong results if characters with values greater than 0xc0 were present in the subject string. (Detail: it assumed UTF-8 input when processing these items.) 16. Added a lot of (int) casts to avoid compiler warnings in systems where size_t is 64-bit (#991). 17. Added a check for running out of memory when PCRE is compiled with --disable-stack-for-recursion (#990). 18. If the last data line in a file for pcretest does not have a newline on the end, a newline was missing in the output. 19. The default pcre_chartables.c file recognizes only ASCII characters (values less than 128) in its various bitmaps. However, there is a facility for generating tables according to the current locale when PCRE is compiled. It turns out that in some environments, 0x85 and 0xa0, which are Unicode space characters, are recognized by isspace() and therefore were getting set in these tables, and indeed these tables seem to approximate to ISO 8859. This caused a problem in UTF-8 mode when pcre_study() was used to create a list of bytes that can start a match. For \s, it was including 0x85 and 0xa0, which of course cannot start UTF-8 characters. I have changed the code so that only real ASCII characters (less than 128) and the correct starting bytes for UTF-8 encodings are set for characters greater than 127 when in UTF-8 mode. (When PCRE_UCP is set - see 9 above - the code is different altogether.) 20. Added the /T option to pcretest so as to be able to run tests with non- standard character tables, thus making it possible to include the tests used for 19 above in the standard set of tests. 21. A pattern such as (?&t)(?#()(?(DEFINE)(?a)) which has a forward reference to a subpattern the other side of a comment that contains an opening parenthesis caused either an internal compiling error, or a reference to the wrong subpattern. Version 8.02 19-Mar-2010 ------------------------ 1. The Unicode data tables have been updated to Unicode 5.2.0. 2. Added the option --libs-cpp to pcre-config, but only when C++ support is configured. 3. Updated the licensing terms in the pcregexp.pas file, as agreed with the original author of that file, following a query about its status. 4. On systems that do not have stdint.h (e.g. Solaris), check for and include inttypes.h instead. This fixes a bug that was introduced by change 8.01/8. 5. A pattern such as (?&t)*+(?(DEFINE)(?.)) which has a possessive quantifier applied to a forward-referencing subroutine call, could compile incorrect code or give the error "internal error: previously-checked referenced subpattern not found". 6. Both MS Visual Studio and Symbian OS have problems with initializing variables to point to external functions. For these systems, therefore, pcre_malloc etc. are now initialized to local functions that call the relevant global functions. 7. There were two entries missing in the vectors called coptable and poptable in pcre_dfa_exec.c. This could lead to memory accesses outsize the vectors. I've fixed the data, and added a kludgy way of testing at compile time that the lengths are correct (equal to the number of opcodes). 8. Following on from 7, I added a similar kludge to check the length of the eint vector in pcreposix.c. 9. Error texts for pcre_compile() are held as one long string to avoid too much relocation at load time. To find a text, the string is searched, counting zeros. There was no check for running off the end of the string, which could happen if a new error number was added without updating the string. 10. \K gave a compile-time error if it appeared in a lookbehind assersion. 11. \K was not working if it appeared in an atomic group or in a group that was called as a "subroutine", or in an assertion. Perl 5.11 documents that \K is "not well defined" if used in an assertion. PCRE now accepts it if the assertion is positive, but not if it is negative. 12. Change 11 fortuitously reduced the size of the stack frame used in the "match()" function of pcre_exec.c by one pointer. Forthcoming implementation of support for (*MARK) will need an extra pointer on the stack; I have reserved it now, so that the stack frame size does not decrease. 13. A pattern such as (?P(?P0)|(?P>L2)(?P>L1)) in which the only other item in branch that calls a recursion is a subroutine call - as in the second branch in the above example - was incorrectly given the compile- time error "recursive call could loop indefinitely" because pcre_compile() was not correctly checking the subroutine for matching a non-empty string. 14. The checks for overrunning compiling workspace could trigger after an overrun had occurred. This is a "should never occur" error, but it can be triggered by pathological patterns such as hundreds of nested parentheses. The checks now trigger 100 bytes before the end of the workspace. 15. Fix typo in configure.ac: "srtoq" should be "strtoq". Version 8.01 19-Jan-2010 ------------------------ 1. If a pattern contained a conditional subpattern with only one branch (in particular, this includes all (*DEFINE) patterns), a call to pcre_study() computed the wrong minimum data length (which is of course zero for such subpatterns). This could cause incorrect "no match" results. 2. For patterns such as (?i)a(?-i)b|c where an option setting at the start of the pattern is reset in the first branch, pcre_compile() failed with "internal error: code overflow at offset...". This happened only when the reset was to the original external option setting. (An optimization abstracts leading options settings into an external setting, which was the cause of this.) 3. A pattern such as ^(?!a(*SKIP)b) where a negative assertion contained one of the verbs SKIP, PRUNE, or COMMIT, did not work correctly. When the assertion pattern did not match (meaning that the assertion was true), it was incorrectly treated as false if the SKIP had been reached during the matching. This also applied to assertions used as conditions. 4. If an item that is not supported by pcre_dfa_exec() was encountered in an assertion subpattern, including such a pattern used as a condition, unpredictable results occurred, instead of the error return PCRE_ERROR_DFA_UITEM. 5. The C++ GlobalReplace function was not working like Perl for the special situation when an empty string is matched. It now does the fancy magic stuff that is necessary. 6. In pcre_internal.h, obsolete includes to setjmp.h and stdarg.h have been removed. (These were left over from very, very early versions of PCRE.) 7. Some cosmetic changes to the code to make life easier when compiling it as part of something else: (a) Change DEBUG to PCRE_DEBUG. (b) In pcre_compile(), rename the member of the "branch_chain" structure called "current" as "current_branch", to prevent a collision with the Linux macro when compiled as a kernel module. (c) In pcre_study(), rename the function set_bit() as set_table_bit(), to prevent a collision with the Linux macro when compiled as a kernel module. 8. In pcre_compile() there are some checks for integer overflows that used to cast potentially large values to (double). This has been changed to that when building, a check for int64_t is made, and if it is found, it is used instead, thus avoiding the use of floating point arithmetic. (There is no other use of FP in PCRE.) If int64_t is not found, the fallback is to double. 9. Added two casts to avoid signed/unsigned warnings from VS Studio Express 2005 (difference between two addresses compared to an unsigned value). 10. Change the standard AC_CHECK_LIB test for libbz2 in configure.ac to a custom one, because of the following reported problem in Windows: - libbz2 uses the Pascal calling convention (WINAPI) for the functions under Win32. - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", therefore missing the function definition. - The compiler thus generates a "C" signature for the test function. - The linker fails to find the "C" function. - PCRE fails to configure if asked to do so against libbz2. 11. When running libtoolize from libtool-2.2.6b as part of autogen.sh, these messages were output: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and rerunning libtoolize, to keep the correct libtool macros in-tree. Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am. I have done both of these things. 12. Although pcre_dfa_exec() does not use nearly as much stack as pcre_exec() most of the time, it *can* run out if it is given a pattern that contains a runaway infinite recursion. I updated the discussion in the pcrestack man page. 13. Now that we have gone to the x.xx style of version numbers, the minor version may start with zero. Using 08 or 09 is a bad idea because users might check the value of PCRE_MINOR in their code, and 08 or 09 may be interpreted as invalid octal numbers. I've updated the previous comment in configure.ac, and also added a check that gives an error if 08 or 09 are used. 14. Change 8.00/11 was not quite complete: code had been accidentally omitted, causing partial matching to fail when the end of the subject matched \W in a UTF-8 pattern where \W was quantified with a minimum of 3. 15. There were some discrepancies between the declarations in pcre_internal.h of _pcre_is_newline(), _pcre_was_newline(), and _pcre_valid_utf8() and their definitions. The declarations used "const uschar *" and the definitions used USPTR. Even though USPTR is normally defined as "const unsigned char *" (and uschar is typedeffed as "unsigned char"), it was reported that: "This difference in casting confuses some C++ compilers, for example, SunCC recognizes above declarations as different functions and generates broken code for hbpcre." I have changed the declarations to use USPTR. 16. GNU libtool is named differently on some systems. The autogen.sh script now tries several variants such as glibtoolize (MacOSX) and libtoolize1x (FreeBSD). 17. Applied Craig's patch that fixes an HP aCC compile error in pcre 8.00 (strtoXX undefined when compiling pcrecpp.cc). The patch contains this comment: "Figure out how to create a longlong from a string: strtoll and equivalent. It's not enough to call AC_CHECK_FUNCS: hpux has a strtoll, for instance, but it only takes 2 args instead of 3!" 18. A subtle bug concerned with back references has been fixed by a change of specification, with a corresponding code fix. A pattern such as ^(xa|=?\1a)+$ which contains a back reference inside the group to which it refers, was giving matches when it shouldn't. For example, xa=xaaa would match that pattern. Interestingly, Perl (at least up to 5.11.3) has the same bug. Such groups have to be quantified to be useful, or contained inside another quantified group. (If there's no repetition, the reference can never match.) The problem arises because, having left the group and moved on to the rest of the pattern, a later failure that backtracks into the group uses the captured value from the final iteration of the group rather than the correct earlier one. I have fixed this in PCRE by forcing any group that contains a reference to itself to be an atomic group; that is, there cannot be any backtracking into it once it has completed. This is similar to recursive and subroutine calls. Version 8.00 19-Oct-09 ---------------------- 1. The table for translating pcre_compile() error codes into POSIX error codes was out-of-date, and there was no check on the pcre_compile() error code being within the table. This could lead to an OK return being given in error. 2. Changed the call to open a subject file in pcregrep from fopen(pathname, "r") to fopen(pathname, "rb"), which fixed a problem with some of the tests in a Windows environment. 3. The pcregrep --count option prints the count for each file even when it is zero, as does GNU grep. However, pcregrep was also printing all files when --files-with-matches was added. Now, when both options are given, it prints counts only for those files that have at least one match. (GNU grep just prints the file name in this circumstance, but including the count seems more useful - otherwise, why use --count?) Also ensured that the combination -clh just lists non-zero counts, with no names. 4. The long form of the pcregrep -F option was incorrectly implemented as --fixed_strings instead of --fixed-strings. This is an incompatible change, but it seems right to fix it, and I didn't think it was worth preserving the old behaviour. 5. The command line items --regex=pattern and --regexp=pattern were not recognized by pcregrep, which required --regex pattern or --regexp pattern (with a space rather than an '='). The man page documented the '=' forms, which are compatible with GNU grep; these now work. 6. No libpcreposix.pc file was created for pkg-config; there was just libpcre.pc and libpcrecpp.pc. The omission has been rectified. 7. Added #ifndef SUPPORT_UCP into the pcre_ucd.c module, to reduce its size when UCP support is not needed, by modifying the Python script that generates it from Unicode data files. This should not matter if the module is correctly used as a library, but I received one complaint about 50K of unwanted data. My guess is that the person linked everything into his program rather than using a library. Anyway, it does no harm. 8. A pattern such as /\x{123}{2,2}+/8 was incorrectly compiled; the trigger was a minimum greater than 1 for a wide character in a possessive repetition. The same bug could also affect patterns like /(\x{ff}{0,2})*/8 which had an unlimited repeat of a nested, fixed maximum repeat of a wide character. Chaos in the form of incorrect output or a compiling loop could result. 9. The restrictions on what a pattern can contain when partial matching is requested for pcre_exec() have been removed. All patterns can now be partially matched by this function. In addition, if there are at least two slots in the offset vector, the offset of the earliest inspected character for the match and the offset of the end of the subject are set in them when PCRE_ERROR_PARTIAL is returned. 10. Partial matching has been split into two forms: PCRE_PARTIAL_SOFT, which is synonymous with PCRE_PARTIAL, for backwards compatibility, and PCRE_PARTIAL_HARD, which causes a partial match to supersede a full match, and may be more useful for multi-segment matching. 11. Partial matching with pcre_exec() is now more intuitive. A partial match used to be given if ever the end of the subject was reached; now it is given only if matching could not proceed because another character was needed. This makes a difference in some odd cases such as Z(*FAIL) with the string "Z", which now yields "no match" instead of "partial match". In the case of pcre_dfa_exec(), "no match" is given if every matching path for the final character ended with (*FAIL). 12. Restarting a match using pcre_dfa_exec() after a partial match did not work if the pattern had a "must contain" character that was already found in the earlier partial match, unless partial matching was again requested. For example, with the pattern /dog.(body)?/, the "must contain" character is "g". If the first part-match was for the string "dog", restarting with "sbody" failed. This bug has been fixed. 13. The string returned by pcre_dfa_exec() after a partial match has been changed so that it starts at the first inspected character rather than the first character of the match. This makes a difference only if the pattern starts with a lookbehind assertion or \b or \B (\K is not supported by pcre_dfa_exec()). It's an incompatible change, but it makes the two matching functions compatible, and I think it's the right thing to do. 14. Added a pcredemo man page, created automatically from the pcredemo.c file, so that the demonstration program is easily available in environments where PCRE has not been installed from source. 15. Arranged to add -DPCRE_STATIC to cflags in libpcre.pc, libpcreposix.cp, libpcrecpp.pc and pcre-config when PCRE is not compiled as a shared library. 16. Added REG_UNGREEDY to the pcreposix interface, at the request of a user. It maps to PCRE_UNGREEDY. It is not, of course, POSIX-compatible, but it is not the first non-POSIX option to be added. Clearly some people find these options useful. 17. If a caller to the POSIX matching function regexec() passes a non-zero value for nmatch with a NULL value for pmatch, the value of nmatch is forced to zero. 18. RunGrepTest did not have a test for the availability of the -u option of the diff command, as RunTest does. It now checks in the same way as RunTest, and also checks for the -b option. 19. If an odd number of negated classes containing just a single character interposed, within parentheses, between a forward reference to a named subpattern and the definition of the subpattern, compilation crashed with an internal error, complaining that it could not find the referenced subpattern. An example of a crashing pattern is /(?&A)(([^m])(?))/. [The bug was that it was starting one character too far in when skipping over the character class, thus treating the ] as data rather than terminating the class. This meant it could skip too much.] 20. Added PCRE_NOTEMPTY_ATSTART in order to be able to correctly implement the /g option in pcretest when the pattern contains \K, which makes it possible to have an empty string match not at the start, even when the pattern is anchored. Updated pcretest and pcredemo to use this option. 21. If the maximum number of capturing subpatterns in a recursion was greater than the maximum at the outer level, the higher number was returned, but with unset values at the outer level. The correct (outer level) value is now given. 22. If (*ACCEPT) appeared inside capturing parentheses, previous releases of PCRE did not set those parentheses (unlike Perl). I have now found a way to make it do so. The string so far is captured, making this feature compatible with Perl. 23. The tests have been re-organized, adding tests 11 and 12, to make it possible to check the Perl 5.10 features against Perl 5.10. 24. Perl 5.10 allows subroutine calls in lookbehinds, as long as the subroutine pattern matches a fixed length string. PCRE did not allow this; now it does. Neither allows recursion. 25. I finally figured out how to implement a request to provide the minimum length of subject string that was needed in order to match a given pattern. (It was back references and recursion that I had previously got hung up on.) This code has now been added to pcre_study(); it finds a lower bound to the length of subject needed. It is not necessarily the greatest lower bound, but using it to avoid searching strings that are too short does give some useful speed-ups. The value is available to calling programs via pcre_fullinfo(). 26. While implementing 25, I discovered to my embarrassment that pcretest had not been passing the result of pcre_study() to pcre_dfa_exec(), so the study optimizations had never been tested with that matching function. Oops. What is worse, even when it was passed study data, there was a bug in pcre_dfa_exec() that meant it never actually used it. Double oops. There were also very few tests of studied patterns with pcre_dfa_exec(). 27. If (?| is used to create subpatterns with duplicate numbers, they are now allowed to have the same name, even if PCRE_DUPNAMES is not set. However, on the other side of the coin, they are no longer allowed to have different names, because these cannot be distinguished in PCRE, and this has caused confusion. (This is a difference from Perl.) 28. When duplicate subpattern names are present (necessarily with different numbers, as required by 27 above), and a test is made by name in a conditional pattern, either for a subpattern having been matched, or for recursion in such a pattern, all the associated numbered subpatterns are tested, and the overall condition is true if the condition is true for any one of them. This is the way Perl works, and is also more like the way testing by number works. Version 7.9 11-Apr-09 --------------------- 1. When building with support for bzlib/zlib (pcregrep) and/or readline (pcretest), all targets were linked against these libraries. This included libpcre, libpcreposix, and libpcrecpp, even though they do not use these libraries. This caused unwanted dependencies to be created. This problem has been fixed, and now only pcregrep is linked with bzlib/zlib and only pcretest is linked with readline. 2. The "typedef int BOOL" in pcre_internal.h that was included inside the "#ifndef FALSE" condition by an earlier change (probably 7.8/18) has been moved outside it again, because FALSE and TRUE are already defined in AIX, but BOOL is not. 3. The pcre_config() function was treating the PCRE_MATCH_LIMIT and PCRE_MATCH_LIMIT_RECURSION values as ints, when they should be long ints. 4. The pcregrep documentation said spaces were inserted as well as colons (or hyphens) following file names and line numbers when outputting matching lines. This is not true; no spaces are inserted. I have also clarified the wording for the --colour (or --color) option. 5. In pcregrep, when --colour was used with -o, the list of matching strings was not coloured; this is different to GNU grep, so I have changed it to be the same. 6. When --colo(u)r was used in pcregrep, only the first matching substring in each matching line was coloured. Now it goes on to look for further matches of any of the test patterns, which is the same behaviour as GNU grep. 7. A pattern that could match an empty string could cause pcregrep to loop; it doesn't make sense to accept an empty string match in pcregrep, so I have locked it out (using PCRE's PCRE_NOTEMPTY option). By experiment, this seems to be how GNU grep behaves. 8. The pattern (?(?=.*b)b|^) was incorrectly compiled as "match must be at start or after a newline", because the conditional assertion was not being correctly handled. The rule now is that both the assertion and what follows in the first alternative must satisfy the test. 9. If auto-callout was enabled in a pattern with a conditional group whose condition was an assertion, PCRE could crash during matching, both with pcre_exec() and pcre_dfa_exec(). 10. The PCRE_DOLLAR_ENDONLY option was not working when pcre_dfa_exec() was used for matching. 11. Unicode property support in character classes was not working for characters (bytes) greater than 127 when not in UTF-8 mode. 12. Added the -M command line option to pcretest. 14. Added the non-standard REG_NOTEMPTY option to the POSIX interface. 15. Added the PCRE_NO_START_OPTIMIZE match-time option. 16. Added comments and documentation about mis-use of no_arg in the C++ wrapper. 17. Implemented support for UTF-8 encoding in EBCDIC environments, a patch from Martin Jerabek that uses macro names for all relevant character and string constants. 18. Added to pcre_internal.h two configuration checks: (a) If both EBCDIC and SUPPORT_UTF8 are set, give an error; (b) If SUPPORT_UCP is set without SUPPORT_UTF8, define SUPPORT_UTF8. The "configure" script handles both of these, but not everybody uses configure. 19. A conditional group that had only one branch was not being correctly recognized as an item that could match an empty string. This meant that an enclosing group might also not be so recognized, causing infinite looping (and probably a segfault) for patterns such as ^"((?(?=[a])[^"])|b)*"$ with the subject "ab", where knowledge that the repeated group can match nothing is needed in order to break the loop. 20. If a pattern that was compiled with callouts was matched using pcre_dfa_ exec(), but without supplying a callout function, matching went wrong. 21. If PCRE_ERROR_MATCHLIMIT occurred during a recursion, there was a memory leak if the size of the offset vector was greater than 30. When the vector is smaller, the saved offsets during recursion go onto a local stack vector, but for larger vectors malloc() is used. It was failing to free when the recursion yielded PCRE_ERROR_MATCH_LIMIT (or any other "abnormal" error, in fact). 22. There was a missing #ifdef SUPPORT_UTF8 round one of the variables in the heapframe that is used only when UTF-8 support is enabled. This caused no problem, but was untidy. 23. Steven Van Ingelgem's patch to CMakeLists.txt to change the name CMAKE_BINARY_DIR to PROJECT_BINARY_DIR so that it works when PCRE is included within another project. 24. Steven Van Ingelgem's patches to add more options to the CMake support, slightly modified by me: (a) PCRE_BUILD_TESTS can be set OFF not to build the tests, including not building pcregrep. (b) PCRE_BUILD_PCREGREP can be see OFF not to build pcregrep, but only if PCRE_BUILD_TESTS is also set OFF, because the tests use pcregrep. 25. Forward references, both numeric and by name, in patterns that made use of duplicate group numbers, could behave incorrectly or give incorrect errors, because when scanning forward to find the reference group, PCRE was not taking into account the duplicate group numbers. A pattern such as ^X(?3)(a)(?|(b)|(q))(Y) is an example. 26. Changed a few more instances of "const unsigned char *" to USPTR, making the feature of a custom pointer more persuasive (as requested by a user). 27. Wrapped the definitions of fileno and isatty for Windows, which appear in pcretest.c, inside #ifndefs, because it seems they are sometimes already pre-defined. 28. Added support for (*UTF8) at the start of a pattern. 29. Arrange for flags added by the "release type" setting in CMake to be shown in the configuration summary. Version 7.8 05-Sep-08 --------------------- 1. Replaced UCP searching code with optimized version as implemented for Ad Muncher (http://www.admuncher.com/) by Peter Kankowski. This uses a two- stage table and inline lookup instead of a function, giving speed ups of 2 to 5 times on some simple patterns that I tested. Permission was given to distribute the MultiStage2.py script that generates the tables (it's not in the tarball, but is in the Subversion repository). 2. Updated the Unicode datatables to Unicode 5.1.0. This adds yet more scripts. 3. Change 12 for 7.7 introduced a bug in pcre_study() when a pattern contained a group with a zero qualifier. The result of the study could be incorrect, or the function might crash, depending on the pattern. 4. Caseless matching was not working for non-ASCII characters in back references. For example, /(\x{de})\1/8i was not matching \x{de}\x{fe}. It now works when Unicode Property Support is available. 5. In pcretest, an escape such as \x{de} in the data was always generating a UTF-8 string, even in non-UTF-8 mode. Now it generates a single byte in non-UTF-8 mode. If the value is greater than 255, it gives a warning about truncation. 6. Minor bugfix in pcrecpp.cc (change "" == ... to NULL == ...). 7. Added two (int) casts to pcregrep when printing the difference of two pointers, in case they are 64-bit values. 8. Added comments about Mac OS X stack usage to the pcrestack man page and to test 2 if it fails. 9. Added PCRE_CALL_CONVENTION just before the names of all exported functions, and a #define of that name to empty if it is not externally set. This is to allow users of MSVC to set it if necessary. 10. The PCRE_EXP_DEFN macro which precedes exported functions was missing from the convenience functions in the pcre_get.c source file. 11. An option change at the start of a pattern that had top-level alternatives could cause overwriting and/or a crash. This command provoked a crash in some environments: printf "/(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]/8\n" | pcretest This potential security problem was recorded as CVE-2008-2371. 12. For a pattern where the match had to start at the beginning or immediately after a newline (e.g /.*anything/ without the DOTALL flag), pcre_exec() and pcre_dfa_exec() could read past the end of the passed subject if there was no match. To help with detecting such bugs (e.g. with valgrind), I modified pcretest so that it places the subject at the end of its malloc-ed buffer. 13. The change to pcretest in 12 above threw up a couple more cases when pcre_ exec() might read past the end of the data buffer in UTF-8 mode. 14. A similar bug to 7.3/2 existed when the PCRE_FIRSTLINE option was set and the data contained the byte 0x85 as part of a UTF-8 character within its first line. This applied both to normal and DFA matching. 15. Lazy qualifiers were not working in some cases in UTF-8 mode. For example, /^[^d]*?$/8 failed to match "abc". 16. Added a missing copyright notice to pcrecpp_internal.h. 17. Make it more clear in the documentation that values returned from pcre_exec() in ovector are byte offsets, not character counts. 18. Tidied a few places to stop certain compilers from issuing warnings. 19. Updated the Virtual Pascal + BCC files to compile the latest v7.7, as supplied by Stefan Weber. I made a further small update for 7.8 because there is a change of source arrangements: the pcre_searchfuncs.c module is replaced by pcre_ucd.c. Version 7.7 07-May-08 --------------------- 1. Applied Craig's patch to sort out a long long problem: "If we can't convert a string to a long long, pretend we don't even have a long long." This is done by checking for the strtoq, strtoll, and _strtoi64 functions. 2. Applied Craig's patch to pcrecpp.cc to restore ABI compatibility with pre-7.6 versions, which defined a global no_arg variable instead of putting it in the RE class. (See also #8 below.) 3. Remove a line of dead code, identified by coverity and reported by Nuno Lopes. 4. Fixed two related pcregrep bugs involving -r with --include or --exclude: (1) The include/exclude patterns were being applied to the whole pathnames of files, instead of just to the final components. (2) If there was more than one level of directory, the subdirectories were skipped unless they satisfied the include/exclude conditions. This is inconsistent with GNU grep (and could even be seen as contrary to the pcregrep specification - which I improved to make it absolutely clear). The action now is always to scan all levels of directory, and just apply the include/exclude patterns to regular files. 5. Added the --include_dir and --exclude_dir patterns to pcregrep, and used --exclude_dir in the tests to avoid scanning .svn directories. 6. Applied Craig's patch to the QuoteMeta function so that it escapes the NUL character as backslash + 0 rather than backslash + NUL, because PCRE doesn't support NULs in patterns. 7. Added some missing "const"s to declarations of static tables in pcre_compile.c and pcre_dfa_exec.c. 8. Applied Craig's patch to pcrecpp.cc to fix a problem in OS X that was caused by fix #2 above. (Subsequently also a second patch to fix the first patch. And a third patch - this was a messy problem.) 9. Applied Craig's patch to remove the use of push_back(). 10. Applied Alan Lehotsky's patch to add REG_STARTEND support to the POSIX matching function regexec(). 11. Added support for the Oniguruma syntax \g, \g, \g'name', \g'n', which, however, unlike Perl's \g{...}, are subroutine calls, not back references. PCRE supports relative numbers with this syntax (I don't think Oniguruma does). 12. Previously, a group with a zero repeat such as (...){0} was completely omitted from the compiled regex. However, this means that if the group was called as a subroutine from elsewhere in the pattern, things went wrong (an internal error was given). Such groups are now left in the compiled pattern, with a new opcode that causes them to be skipped at execution time. 13. Added the PCRE_JAVASCRIPT_COMPAT option. This makes the following changes to the way PCRE behaves: (a) A lone ] character is dis-allowed (Perl treats it as data). (b) A back reference to an unmatched subpattern matches an empty string (Perl fails the current match path). (c) A data ] in a character class must be notated as \] because if the first data character in a class is ], it defines an empty class. (In Perl it is not possible to have an empty class.) The empty class [] never matches; it forces failure and is equivalent to (*FAIL) or (?!). The negative empty class [^] matches any one character, independently of the DOTALL setting. 14. A pattern such as /(?2)[]a()b](abc)/ which had a forward reference to a non-existent subpattern following a character class starting with ']' and containing () gave an internal compiling error instead of "reference to non-existent subpattern". Fortunately, when the pattern did exist, the compiled code was correct. (When scanning forwards to check for the existencd of the subpattern, it was treating the data ']' as terminating the class, so got the count wrong. When actually compiling, the reference was subsequently set up correctly.) 15. The "always fail" assertion (?!) is optimzed to (*FAIL) by pcre_compile; it was being rejected as not supported by pcre_dfa_exec(), even though other assertions are supported. I have made pcre_dfa_exec() support (*FAIL). 16. The implementation of 13c above involved the invention of a new opcode, OP_ALLANY, which is like OP_ANY but doesn't check the /s flag. Since /s cannot be changed at match time, I realized I could make a small improvement to matching performance by compiling OP_ALLANY instead of OP_ANY for "." when DOTALL was set, and then removing the runtime tests on the OP_ANY path. 17. Compiling pcretest on Windows with readline support failed without the following two fixes: (1) Make the unistd.h include conditional on HAVE_UNISTD_H; (2) #define isatty and fileno as _isatty and _fileno. 18. Changed CMakeLists.txt and cmake/FindReadline.cmake to arrange for the ncurses library to be included for pcretest when ReadLine support is requested, but also to allow for it to be overridden. This patch came from Daniel Bergström. 19. There was a typo in the file ucpinternal.h where f0_rangeflag was defined as 0x00f00000 instead of 0x00800000. Luckily, this would not have caused any errors with the current Unicode tables. Thanks to Peter Kankowski for spotting this. Version 7.6 28-Jan-08 --------------------- 1. A character class containing a very large number of characters with codepoints greater than 255 (in UTF-8 mode, of course) caused a buffer overflow. 2. Patch to cut out the "long long" test in pcrecpp_unittest when HAVE_LONG_LONG is not defined. 3. Applied Christian Ehrlicher's patch to update the CMake build files to bring them up to date and include new features. This patch includes: - Fixed PH's badly added libz and libbz2 support. - Fixed a problem with static linking. - Added pcredemo. [But later removed - see 7 below.] - Fixed dftables problem and added an option. - Added a number of HAVE_XXX tests, including HAVE_WINDOWS_H and HAVE_LONG_LONG. - Added readline support for pcretest. - Added an listing of the option settings after cmake has run. 4. A user submitted a patch to Makefile that makes it easy to create "pcre.dll" under mingw when using Configure/Make. I added stuff to Makefile.am that cause it to include this special target, without affecting anything else. Note that the same mingw target plus all the other distribution libraries and programs are now supported when configuring with CMake (see 6 below) instead of with Configure/Make. 5. Applied Craig's patch that moves no_arg into the RE class in the C++ code. This is an attempt to solve the reported problem "pcrecpp::no_arg is not exported in the Windows port". It has not yet been confirmed that the patch solves the problem, but it does no harm. 6. Applied Sheri's patch to CMakeLists.txt to add NON_STANDARD_LIB_PREFIX and NON_STANDARD_LIB_SUFFIX for dll names built with mingw when configured with CMake, and also correct the comment about stack recursion. 7. Remove the automatic building of pcredemo from the ./configure system and from CMakeLists.txt. The whole idea of pcredemo.c is that it is an example of a program that users should build themselves after PCRE is installed, so building it automatically is not really right. What is more, it gave trouble in some build environments. 8. Further tidies to CMakeLists.txt from Sheri and Christian. Version 7.5 10-Jan-08 --------------------- 1. Applied a patch from Craig: "This patch makes it possible to 'ignore' values in parens when parsing an RE using the C++ wrapper." 2. Negative specials like \S did not work in character classes in UTF-8 mode. Characters greater than 255 were excluded from the class instead of being included. 3. The same bug as (2) above applied to negated POSIX classes such as [:^space:]. 4. PCRECPP_STATIC was referenced in pcrecpp_internal.h, but nowhere was it defined or documented. It seems to have been a typo for PCRE_STATIC, so I have changed it. 5. The construct (?&) was not diagnosed as a syntax error (it referenced the first named subpattern) and a construct such as (?&a) would reference the first named subpattern whose name started with "a" (in other words, the length check was missing). Both these problems are fixed. "Subpattern name expected" is now given for (?&) (a zero-length name), and this patch also makes it give the same error for \k'' (previously it complained that that was a reference to a non-existent subpattern). 6. The erroneous patterns (?+-a) and (?-+a) give different error messages; this is right because (?- can be followed by option settings as well as by digits. I have, however, made the messages clearer. 7. Patterns such as (?(1)a|b) (a pattern that contains fewer subpatterns than the number used in the conditional) now cause a compile-time error. This is actually not compatible with Perl, which accepts such patterns, but treats the conditional as always being FALSE (as PCRE used to), but it seems to me that giving a diagnostic is better. 8. Change "alphameric" to the more common word "alphanumeric" in comments and messages. 9. Fix two occurrences of "backslash" in comments that should have been "backspace". 10. Remove two redundant lines of code that can never be obeyed (their function was moved elsewhere). 11. The program that makes PCRE's Unicode character property table had a bug which caused it to generate incorrect table entries for sequences of characters that have the same character type, but are in different scripts. It amalgamated them into a single range, with the script of the first of them. In other words, some characters were in the wrong script. There were thirteen such cases, affecting characters in the following ranges: U+002b0 - U+002c1 U+0060c - U+0060d U+0061e - U+00612 U+0064b - U+0065e U+0074d - U+0076d U+01800 - U+01805 U+01d00 - U+01d77 U+01d9b - U+01dbf U+0200b - U+0200f U+030fc - U+030fe U+03260 - U+0327f U+0fb46 - U+0fbb1 U+10450 - U+1049d 12. The -o option (show only the matching part of a line) for pcregrep was not compatible with GNU grep in that, if there was more than one match in a line, it showed only the first of them. It now behaves in the same way as GNU grep. 13. If the -o and -v options were combined for pcregrep, it printed a blank line for every non-matching line. GNU grep prints nothing, and pcregrep now does the same. The return code can be used to tell if there were any non-matching lines. 14. Added --file-offsets and --line-offsets to pcregrep. 15. The pattern (?=something)(?R) was not being diagnosed as a potentially infinitely looping recursion. The bug was that positive lookaheads were not being skipped when checking for a possible empty match (negative lookaheads and both kinds of lookbehind were skipped). 16. Fixed two typos in the Windows-only code in pcregrep.c, and moved the inclusion of to before rather than after the definition of INVALID_FILE_ATTRIBUTES (patch from David Byron). 17. Specifying a possessive quantifier with a specific limit for a Unicode character property caused pcre_compile() to compile bad code, which led at runtime to PCRE_ERROR_INTERNAL (-14). Examples of patterns that caused this are: /\p{Zl}{2,3}+/8 and /\p{Cc}{2}+/8. It was the possessive "+" that caused the error; without that there was no problem. 18. Added --enable-pcregrep-libz and --enable-pcregrep-libbz2. 19. Added --enable-pcretest-libreadline. 20. In pcrecpp.cc, the variable 'count' was incremented twice in RE::GlobalReplace(). As a result, the number of replacements returned was double what it should be. I removed one of the increments, but Craig sent a later patch that removed the other one (the right fix) and added unit tests that check the return values (which was not done before). 21. Several CMake things: (1) Arranged that, when cmake is used on Unix, the libraries end up with the names libpcre and libpcreposix, not just pcre and pcreposix. (2) The above change means that pcretest and pcregrep are now correctly linked with the newly-built libraries, not previously installed ones. (3) Added PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, PCRE_SUPPORT_LIBBZ2. 22. In UTF-8 mode, with newline set to "any", a pattern such as .*a.*=.b.* crashed when matching a string such as a\x{2029}b (note that \x{2029} is a UTF-8 newline character). The key issue is that the pattern starts .*; this means that the match must be either at the beginning, or after a newline. The bug was in the code for advancing after a failed match and checking that the new position followed a newline. It was not taking account of UTF-8 characters correctly. 23. PCRE was behaving differently from Perl in the way it recognized POSIX character classes. PCRE was not treating the sequence [:...:] as a character class unless the ... were all letters. Perl, however, seems to allow any characters between [: and :], though of course it rejects as unknown any "names" that contain non-letters, because all the known class names consist only of letters. Thus, Perl gives an error for [[:1234:]], for example, whereas PCRE did not - it did not recognize a POSIX character class. This seemed a bit dangerous, so the code has been changed to be closer to Perl. The behaviour is not identical to Perl, because PCRE will diagnose an unknown class for, for example, [[:l\ower:]] where Perl will treat it as [[:lower:]]. However, PCRE does now give "unknown" errors where Perl does, and where it didn't before. 24. Rewrite so as to remove the single use of %n from pcregrep because in some Windows environments %n is disabled by default. Version 7.4 21-Sep-07 --------------------- 1. Change 7.3/28 was implemented for classes by looking at the bitmap. This means that a class such as [\s] counted as "explicit reference to CR or LF". That isn't really right - the whole point of the change was to try to help when there was an actual mention of one of the two characters. So now the change happens only if \r or \n (or a literal CR or LF) character is encountered. 2. The 32-bit options word was also used for 6 internal flags, but the numbers of both had grown to the point where there were only 3 bits left. Fortunately, there was spare space in the data structure, and so I have moved the internal flags into a new 16-bit field to free up more option bits. 3. The appearance of (?J) at the start of a pattern set the DUPNAMES option, but did not set the internal JCHANGED flag - either of these is enough to control the way the "get" function works - but the PCRE_INFO_JCHANGED facility is supposed to tell if (?J) was ever used, so now (?J) at the start sets both bits. 4. Added options (at build time, compile time, exec time) to change \R from matching any Unicode line ending sequence to just matching CR, LF, or CRLF. 5. doc/pcresyntax.html was missing from the distribution. 6. Put back the definition of PCRE_ERROR_NULLWSLIMIT, for backward compatibility, even though it is no longer used. 7. Added macro for snprintf to pcrecpp_unittest.cc and also for strtoll and strtoull to pcrecpp.cc to select the available functions in WIN32 when the windows.h file is present (where different names are used). [This was reversed later after testing - see 16 below.] 8. Changed all #include to #include "config.h". There were also some further cases that I changed to "pcre.h". 9. When pcregrep was used with the --colour option, it missed the line ending sequence off the lines that it output. 10. It was pointed out to me that arrays of string pointers cause lots of relocations when a shared library is dynamically loaded. A technique of using a single long string with a table of offsets can drastically reduce these. I have refactored PCRE in four places to do this. The result is dramatic: Originally: 290 After changing UCP table: 187 After changing error message table: 43 After changing table of "verbs" 36 After changing table of Posix names 22 Thanks to the folks working on Gregex for glib for this insight. 11. --disable-stack-for-recursion caused compiling to fail unless -enable- unicode-properties was also set. 12. Updated the tests so that they work when \R is defaulted to ANYCRLF. 13. Added checks for ANY and ANYCRLF to pcrecpp.cc where it previously checked only for CRLF. 14. Added casts to pcretest.c to avoid compiler warnings. 15. Added Craig's patch to various pcrecpp modules to avoid compiler warnings. 16. Added Craig's patch to remove the WINDOWS_H tests, that were not working, and instead check for _strtoi64 explicitly, and avoid the use of snprintf() entirely. This removes changes made in 7 above. 17. The CMake files have been updated, and there is now more information about building with CMake in the NON-UNIX-USE document. Version 7.3 28-Aug-07 --------------------- 1. In the rejigging of the build system that eventually resulted in 7.1, the line "#include " was included in pcre_internal.h. The use of angle brackets there is not right, since it causes compilers to look for an installed pcre.h, not the version that is in the source that is being compiled (which of course may be different). I have changed it back to: #include "pcre.h" I have a vague recollection that the change was concerned with compiling in different directories, but in the new build system, that is taken care of by the VPATH setting the Makefile. 2. The pattern .*$ when run in not-DOTALL UTF-8 mode with newline=any failed when the subject happened to end in the byte 0x85 (e.g. if the last character was \x{1ec5}). *Character* 0x85 is one of the "any" newline characters but of course it shouldn't be taken as a newline when it is part of another character. The bug was that, for an unlimited repeat of . in not-DOTALL UTF-8 mode, PCRE was advancing by bytes rather than by characters when looking for a newline. 3. A small performance improvement in the DOTALL UTF-8 mode .* case. 4. Debugging: adjusted the names of opcodes for different kinds of parentheses in debug output. 5. Arrange to use "%I64d" instead of "%lld" and "%I64u" instead of "%llu" for long printing in the pcrecpp unittest when running under MinGW. 6. ESC_K was left out of the EBCDIC table. 7. Change 7.0/38 introduced a new limit on the number of nested non-capturing parentheses; I made it 1000, which seemed large enough. Unfortunately, the limit also applies to "virtual nesting" when a pattern is recursive, and in this case 1000 isn't so big. I have been able to remove this limit at the expense of backing off one optimization in certain circumstances. Normally, when pcre_exec() would call its internal match() function recursively and immediately return the result unconditionally, it uses a "tail recursion" feature to save stack. However, when a subpattern that can match an empty string has an unlimited repetition quantifier, it no longer makes this optimization. That gives it a stack frame in which to save the data for checking that an empty string has been matched. Previously this was taken from the 1000-entry workspace that had been reserved. So now there is no explicit limit, but more stack is used. 8. Applied Daniel's patches to solve problems with the import/export magic syntax that is required for Windows, and which was going wrong for the pcreposix and pcrecpp parts of the library. These were overlooked when this problem was solved for the main library. 9. There were some crude static tests to avoid integer overflow when computing the size of patterns that contain repeated groups with explicit upper limits. As the maximum quantifier is 65535, the maximum group length was set at 30,000 so that the product of these two numbers did not overflow a 32-bit integer. However, it turns out that people want to use groups that are longer than 30,000 bytes (though not repeat them that many times). Change 7.0/17 (the refactoring of the way the pattern size is computed) has made it possible to implement the integer overflow checks in a much more dynamic way, which I have now done. The artificial limitation on group length has been removed - we now have only the limit on the total length of the compiled pattern, which depends on the LINK_SIZE setting. 10. Fixed a bug in the documentation for get/copy named substring when duplicate names are permitted. If none of the named substrings are set, the functions return PCRE_ERROR_NOSUBSTRING (7); the doc said they returned an empty string. 11. Because Perl interprets \Q...\E at a high level, and ignores orphan \E instances, patterns such as [\Q\E] or [\E] or even [^\E] cause an error, because the ] is interpreted as the first data character and the terminating ] is not found. PCRE has been made compatible with Perl in this regard. Previously, it interpreted [\Q\E] as an empty class, and [\E] could cause memory overwriting. 10. Like Perl, PCRE automatically breaks an unlimited repeat after an empty string has been matched (to stop an infinite loop). It was not recognizing a conditional subpattern that could match an empty string if that subpattern was within another subpattern. For example, it looped when trying to match (((?(1)X|))*) but it was OK with ((?(1)X|)*) where the condition was not nested. This bug has been fixed. 12. A pattern like \X?\d or \P{L}?\d in non-UTF-8 mode could cause a backtrack past the start of the subject in the presence of bytes with the top bit set, for example "\x8aBCD". 13. Added Perl 5.10 experimental backtracking controls (*FAIL), (*F), (*PRUNE), (*SKIP), (*THEN), (*COMMIT), and (*ACCEPT). 14. Optimized (?!) to (*FAIL). 15. Updated the test for a valid UTF-8 string to conform to the later RFC 3629. This restricts code points to be within the range 0 to 0x10FFFF, excluding the "low surrogate" sequence 0xD800 to 0xDFFF. Previously, PCRE allowed the full range 0 to 0x7FFFFFFF, as defined by RFC 2279. Internally, it still does: it's just the validity check that is more restrictive. 16. Inserted checks for integer overflows during escape sequence (backslash) processing, and also fixed erroneous offset values for syntax errors during backslash processing. 17. Fixed another case of looking too far back in non-UTF-8 mode (cf 12 above) for patterns like [\PPP\x8a]{1,}\x80 with the subject "A\x80". 18. An unterminated class in a pattern like (?1)\c[ with a "forward reference" caused an overrun. 19. A pattern like (?:[\PPa*]*){8,} which had an "extended class" (one with something other than just ASCII characters) inside a group that had an unlimited repeat caused a loop at compile time (while checking to see whether the group could match an empty string). 20. Debugging a pattern containing \p or \P could cause a crash. For example, [\P{Any}] did so. (Error in the code for printing property names.) 21. An orphan \E inside a character class could cause a crash. 22. A repeated capturing bracket such as (A)? could cause a wild memory reference during compilation. 23. There are several functions in pcre_compile() that scan along a compiled expression for various reasons (e.g. to see if it's fixed length for look behind). There were bugs in these functions when a repeated \p or \P was present in the pattern. These operators have additional parameters compared with \d, etc, and these were not being taken into account when moving along the compiled data. Specifically: (a) A item such as \p{Yi}{3} in a lookbehind was not treated as fixed length. (b) An item such as \pL+ within a repeated group could cause crashes or loops. (c) A pattern such as \p{Yi}+(\P{Yi}+)(?1) could give an incorrect "reference to non-existent subpattern" error. (d) A pattern like (\P{Yi}{2}\277)? could loop at compile time. 24. A repeated \S or \W in UTF-8 mode could give wrong answers when multibyte characters were involved (for example /\S{2}/8g with "A\x{a3}BC"). 25. Using pcregrep in multiline, inverted mode (-Mv) caused it to loop. 26. Patterns such as [\P{Yi}A] which include \p or \P and just one other character were causing crashes (broken optimization). 27. Patterns such as (\P{Yi}*\277)* (group with possible zero repeat containing \p or \P) caused a compile-time loop. 28. More problems have arisen in unanchored patterns when CRLF is a valid line break. For example, the unstudied pattern [\r\n]A does not match the string "\r\nA" because change 7.0/46 below moves the current point on by two characters after failing to match at the start. However, the pattern \nA *does* match, because it doesn't start till \n, and if [\r\n]A is studied, the same is true. There doesn't seem any very clean way out of this, but what I have chosen to do makes the common cases work: PCRE now takes note of whether there can be an explicit match for \r or \n anywhere in the pattern, and if so, 7.0/46 no longer applies. As part of this change, there's a new PCRE_INFO_HASCRORLF option for finding out whether a compiled pattern has explicit CR or LF references. 29. Added (*CR) etc for changing newline setting at start of pattern. Version 7.2 19-Jun-07 --------------------- 1. If the fr_FR locale cannot be found for test 3, try the "french" locale, which is apparently normally available under Windows. 2. Re-jig the pcregrep tests with different newline settings in an attempt to make them independent of the local environment's newline setting. 3. Add code to configure.ac to remove -g from the CFLAGS default settings. 4. Some of the "internals" tests were previously cut out when the link size was not 2, because the output contained actual offsets. The recent new "Z" feature of pcretest means that these can be cut out, making the tests usable with all link sizes. 5. Implemented Stan Switzer's goto replacement for longjmp() when not using stack recursion. This gives a massive performance boost under BSD, but just a small improvement under Linux. However, it saves one field in the frame in all cases. 6. Added more features from the forthcoming Perl 5.10: (a) (?-n) (where n is a string of digits) is a relative subroutine or recursion call. It refers to the nth most recently opened parentheses. (b) (?+n) is also a relative subroutine call; it refers to the nth next to be opened parentheses. (c) Conditions that refer to capturing parentheses can be specified relatively, for example, (?(-2)... or (?(+3)... (d) \K resets the start of the current match so that everything before is not part of it. (e) \k{name} is synonymous with \k and \k'name' (.NET compatible). (f) \g{name} is another synonym - part of Perl 5.10's unification of reference syntax. (g) (?| introduces a group in which the numbering of parentheses in each alternative starts with the same number. (h) \h, \H, \v, and \V match horizontal and vertical whitespace. 7. Added two new calls to pcre_fullinfo(): PCRE_INFO_OKPARTIAL and PCRE_INFO_JCHANGED. 8. A pattern such as (.*(.)?)* caused pcre_exec() to fail by either not terminating or by crashing. Diagnosed by Viktor Griph; it was in the code for detecting groups that can match an empty string. 9. A pattern with a very large number of alternatives (more than several hundred) was running out of internal workspace during the pre-compile phase, where pcre_compile() figures out how much memory will be needed. A bit of new cunning has reduced the workspace needed for groups with alternatives. The 1000-alternative test pattern now uses 12 bytes of workspace instead of running out of the 4096 that are available. 10. Inserted some missing (unsigned int) casts to get rid of compiler warnings. 11. Applied patch from Google to remove an optimization that didn't quite work. The report of the bug said: pcrecpp::RE("a*").FullMatch("aaa") matches, while pcrecpp::RE("a*?").FullMatch("aaa") does not, and pcrecpp::RE("a*?\\z").FullMatch("aaa") does again. 12. If \p or \P was used in non-UTF-8 mode on a character greater than 127 it matched the wrong number of bytes. Version 7.1 24-Apr-07 --------------------- 1. Applied Bob Rossi and Daniel G's patches to convert the build system to one that is more "standard", making use of automake and other Autotools. There is some re-arrangement of the files and adjustment of comments consequent on this. 2. Part of the patch fixed a problem with the pcregrep tests. The test of -r for recursive directory scanning broke on some systems because the files are not scanned in any specific order and on different systems the order was different. A call to "sort" has been inserted into RunGrepTest for the approprate test as a short-term fix. In the longer term there may be an alternative. 3. I had an email from Eric Raymond about problems translating some of PCRE's man pages to HTML (despite the fact that I distribute HTML pages, some people do their own conversions for various reasons). The problems concerned the use of low-level troff macros .br and .in. I have therefore removed all such uses from the man pages (some were redundant, some could be replaced by .nf/.fi pairs). The 132html script that I use to generate HTML has been updated to handle .nf/.fi and to complain if it encounters .br or .in. 4. Updated comments in configure.ac that get placed in config.h.in and also arranged for config.h to be included in the distribution, with the name config.h.generic, for the benefit of those who have to compile without Autotools (compare pcre.h, which is now distributed as pcre.h.generic). 5. Updated the support (such as it is) for Virtual Pascal, thanks to Stefan Weber: (1) pcre_internal.h was missing some function renames; (2) updated makevp.bat for the current PCRE, using the additional files makevp_c.txt, makevp_l.txt, and pcregexp.pas. 6. A Windows user reported a minor discrepancy with test 2, which turned out to be caused by a trailing space on an input line that had got lost in his copy. The trailing space was an accident, so I've just removed it. 7. Add -Wl,-R... flags in pcre-config.in for *BSD* systems, as I'm told that is needed. 8. Mark ucp_table (in ucptable.h) and ucp_gentype (in pcre_ucp_searchfuncs.c) as "const" (a) because they are and (b) because it helps the PHP maintainers who have recently made a script to detect big data structures in the php code that should be moved to the .rodata section. I remembered to update Builducptable as well, so it won't revert if ucptable.h is ever re-created. 9. Added some extra #ifdef SUPPORT_UTF8 conditionals into pcretest.c, pcre_printint.src, pcre_compile.c, pcre_study.c, and pcre_tables.c, in order to be able to cut out the UTF-8 tables in the latter when UTF-8 support is not required. This saves 1.5-2K of code, which is important in some applications. Later: more #ifdefs are needed in pcre_ord2utf8.c and pcre_valid_utf8.c so as not to refer to the tables, even though these functions will never be called when UTF-8 support is disabled. Otherwise there are problems with a shared library. 10. Fixed two bugs in the emulated memmove() function in pcre_internal.h: (a) It was defining its arguments as char * instead of void *. (b) It was assuming that all moves were upwards in memory; this was true a long time ago when I wrote it, but is no longer the case. The emulated memove() is provided for those environments that have neither memmove() nor bcopy(). I didn't think anyone used it these days, but that is clearly not the case, as these two bugs were recently reported. 11. The script PrepareRelease is now distributed: it calls 132html, CleanTxt, and Detrail to create the HTML documentation, the .txt form of the man pages, and it removes trailing spaces from listed files. It also creates pcre.h.generic and config.h.generic from pcre.h and config.h. In the latter case, it wraps all the #defines with #ifndefs. This script should be run before "make dist". 12. Fixed two fairly obscure bugs concerned with quantified caseless matching with Unicode property support. (a) For a maximizing quantifier, if the two different cases of the character were of different lengths in their UTF-8 codings (there are some cases like this - I found 11), and the matching function had to back up over a mixture of the two cases, it incorrectly assumed they were both the same length. (b) When PCRE was configured to use the heap rather than the stack for recursion during matching, it was not correctly preserving the data for the other case of a UTF-8 character when checking ahead for a match while processing a minimizing repeat. If the check also involved matching a wide character, but failed, corruption could cause an erroneous result when trying to check for a repeat of the original character. 13. Some tidying changes to the testing mechanism: (a) The RunTest script now detects the internal link size and whether there is UTF-8 and UCP support by running ./pcretest -C instead of relying on values substituted by "configure". (The RunGrepTest script already did this for UTF-8.) The configure.ac script no longer substitutes the relevant variables. (b) The debugging options /B and /D in pcretest show the compiled bytecode with length and offset values. This means that the output is different for different internal link sizes. Test 2 is skipped for link sizes other than 2 because of this, bypassing the problem. Unfortunately, there was also a test in test 3 (the locale tests) that used /B and failed for link sizes other than 2. Rather than cut the whole test out, I have added a new /Z option to pcretest that replaces the length and offset values with spaces. This is now used to make test 3 independent of link size. (Test 2 will be tidied up later.) 14. If erroroffset was passed as NULL to pcre_compile, it provoked a segmentation fault instead of returning the appropriate error message. 15. In multiline mode when the newline sequence was set to "any", the pattern ^$ would give a match between the \r and \n of a subject such as "A\r\nB". This doesn't seem right; it now treats the CRLF combination as the line ending, and so does not match in that case. It's only a pattern such as ^$ that would hit this one: something like ^ABC$ would have failed after \r and then tried again after \r\n. 16. Changed the comparison command for RunGrepTest from "diff -u" to "diff -ub" in an attempt to make files that differ only in their line terminators compare equal. This works on Linux. 17. Under certain error circumstances pcregrep might try to free random memory as it exited. This is now fixed, thanks to valgrind. 19. In pcretest, if the pattern /(?m)^$/g was matched against the string "abc\r\n\r\n", it found an unwanted second match after the second \r. This was because its rules for how to advance for /g after matching an empty string at the end of a line did not allow for this case. They now check for it specially. 20. pcretest is supposed to handle patterns and data of any length, by extending its buffers when necessary. It was getting this wrong when the buffer for a data line had to be extended. 21. Added PCRE_NEWLINE_ANYCRLF which is like ANY, but matches only CR, LF, or CRLF as a newline sequence. 22. Code for handling Unicode properties in pcre_dfa_exec() wasn't being cut out by #ifdef SUPPORT_UCP. This did no harm, as it could never be used, but I have nevertheless tidied it up. 23. Added some casts to kill warnings from HP-UX ia64 compiler. 24. Added a man page for pcre-config. Version 7.0 19-Dec-06 --------------------- 1. Fixed a signed/unsigned compiler warning in pcre_compile.c, shown up by moving to gcc 4.1.1. 2. The -S option for pcretest uses setrlimit(); I had omitted to #include sys/time.h, which is documented as needed for this function. It doesn't seem to matter on Linux, but it showed up on some releases of OS X. 3. It seems that there are systems where bytes whose values are greater than 127 match isprint() in the "C" locale. The "C" locale should be the default when a C program starts up. In most systems, only ASCII printing characters match isprint(). This difference caused the output from pcretest to vary, making some of the tests fail. I have changed pcretest so that: (a) When it is outputting text in the compiled version of a pattern, bytes other than 32-126 are always shown as hex escapes. (b) When it is outputting text that is a matched part of a subject string, it does the same, unless a different locale has been set for the match (using the /L modifier). In this case, it uses isprint() to decide. 4. Fixed a major bug that caused incorrect computation of the amount of memory required for a compiled pattern when options that changed within the pattern affected the logic of the preliminary scan that determines the length. The relevant options are -x, and -i in UTF-8 mode. The result was that the computed length was too small. The symptoms of this bug were either the PCRE error "internal error: code overflow" from pcre_compile(), or a glibc crash with a message such as "pcretest: free(): invalid next size (fast)". Examples of patterns that provoked this bug (shown in pcretest format) are: /(?-x: )/x /(?x)(?-x: \s*#\s*)/ /((?i)[\x{c0}])/8 /(?i:[\x{c0}])/8 HOWEVER: Change 17 below makes this fix obsolete as the memory computation is now done differently. 5. Applied patches from Google to: (a) add a QuoteMeta function to the C++ wrapper classes; (b) implement a new function in the C++ scanner that is more efficient than the old way of doing things because it avoids levels of recursion in the regex matching; (c) add a paragraph to the documentation for the FullMatch() function. 6. The escape sequence \n was being treated as whatever was defined as "newline". Not only was this contrary to the documentation, which states that \n is character 10 (hex 0A), but it also went horribly wrong when "newline" was defined as CRLF. This has been fixed. 7. In pcre_dfa_exec.c the value of an unsigned integer (the variable called c) was being set to -1 for the "end of line" case (supposedly a value that no character can have). Though this value is never used (the check for end of line is "zero bytes in current character"), it caused compiler complaints. I've changed it to 0xffffffff. 8. In pcre_version.c, the version string was being built by a sequence of C macros that, in the event of PCRE_PRERELEASE being defined as an empty string (as it is for production releases) called a macro with an empty argument. The C standard says the result of this is undefined. The gcc compiler treats it as an empty string (which was what was wanted) but it is reported that Visual C gives an error. The source has been hacked around to avoid this problem. 9. On the advice of a Windows user, included and in Windows builds of pcretest, and changed the call to _setmode() to use _O_BINARY instead of 0x8000. Made all the #ifdefs test both _WIN32 and WIN32 (not all of them did). 10. Originally, pcretest opened its input and output without "b"; then I was told that "b" was needed in some environments, so it was added for release 5.0 to both the input and output. (It makes no difference on Unix-like systems.) Later I was told that it is wrong for the input on Windows. I've now abstracted the modes into two macros, to make it easier to fiddle with them, and removed "b" from the input mode under Windows. 11. Added pkgconfig support for the C++ wrapper library, libpcrecpp. 12. Added -help and --help to pcretest as an official way of being reminded of the options. 13. Removed some redundant semicolons after macro calls in pcrecpparg.h.in and pcrecpp.cc because they annoy compilers at high warning levels. 14. A bit of tidying/refactoring in pcre_exec.c in the main bumpalong loop. 15. Fixed an occurrence of == in configure.ac that should have been = (shell scripts are not C programs :-) and which was not noticed because it works on Linux. 16. pcretest is supposed to handle any length of pattern and data line (as one line or as a continued sequence of lines) by extending its input buffer if necessary. This feature was broken for very long pattern lines, leading to a string of junk being passed to pcre_compile() if the pattern was longer than about 50K. 17. I have done a major re-factoring of the way pcre_compile() computes the amount of memory needed for a compiled pattern. Previously, there was code that made a preliminary scan of the pattern in order to do this. That was OK when PCRE was new, but as the facilities have expanded, it has become harder and harder to keep it in step with the real compile phase, and there have been a number of bugs (see for example, 4 above). I have now found a cunning way of running the real compile function in a "fake" mode that enables it to compute how much memory it would need, while actually only ever using a few hundred bytes of working memory and without too many tests of the mode. This should make future maintenance and development easier. A side effect of this work is that the limit of 200 on the nesting depth of parentheses has been removed (though this was never a serious limitation, I suspect). However, there is a downside: pcre_compile() now runs more slowly than before (30% or more, depending on the pattern). I hope this isn't a big issue. There is no effect on runtime performance. 18. Fixed a minor bug in pcretest: if a pattern line was not terminated by a newline (only possible for the last line of a file) and it was a pattern that set a locale (followed by /Lsomething), pcretest crashed. 19. Added additional timing features to pcretest. (1) The -tm option now times matching only, not compiling. (2) Both -t and -tm can be followed, as a separate command line item, by a number that specifies the number of repeats to use when timing. The default is 50000; this gives better precision, but takes uncomfortably long for very large patterns. 20. Extended pcre_study() to be more clever in cases where a branch of a subpattern has no definite first character. For example, (a*|b*)[cd] would previously give no result from pcre_study(). Now it recognizes that the first character must be a, b, c, or d. 21. There was an incorrect error "recursive call could loop indefinitely" if a subpattern (or the entire pattern) that was being tested for matching an empty string contained only one non-empty item after a nested subpattern. For example, the pattern (?>\x{100}*)\d(?R) provoked this error incorrectly, because the \d was being skipped in the check. 22. The pcretest program now has a new pattern option /B and a command line option -b, which is equivalent to adding /B to every pattern. This causes it to show the compiled bytecode, without the additional information that -d shows. The effect of -d is now the same as -b with -i (and similarly, /D is the same as /B/I). 23. A new optimization is now able automatically to treat some sequences such as a*b as a*+b. More specifically, if something simple (such as a character or a simple class like \d) has an unlimited quantifier, and is followed by something that cannot possibly match the quantified thing, the quantifier is automatically "possessified". 24. A recursive reference to a subpattern whose number was greater than 39 went wrong under certain circumstances in UTF-8 mode. This bug could also have affected the operation of pcre_study(). 25. Realized that a little bit of performance could be had by replacing (c & 0xc0) == 0xc0 with c >= 0xc0 when processing UTF-8 characters. 26. Timing data from pcretest is now shown to 4 decimal places instead of 3. 27. Possessive quantifiers such as a++ were previously implemented by turning them into atomic groups such as ($>a+). Now they have their own opcodes, which improves performance. This includes the automatically created ones from 23 above. 28. A pattern such as (?=(\w+))\1: which simulates an atomic group using a lookahead was broken if it was not anchored. PCRE was mistakenly expecting the first matched character to be a colon. This applied both to named and numbered groups. 29. The ucpinternal.h header file was missing its idempotency #ifdef. 30. I was sent a "project" file called libpcre.a.dev which I understand makes building PCRE on Windows easier, so I have included it in the distribution. 31. There is now a check in pcretest against a ridiculously large number being returned by pcre_exec() or pcre_dfa_exec(). If this happens in a /g or /G loop, the loop is abandoned. 32. Forward references to subpatterns in conditions such as (?(2)...) where subpattern 2 is defined later cause pcre_compile() to search forwards in the pattern for the relevant set of parentheses. This search went wrong when there were unescaped parentheses in a character class, parentheses escaped with \Q...\E, or parentheses in a #-comment in /x mode. 33. "Subroutine" calls and backreferences were previously restricted to referencing subpatterns earlier in the regex. This restriction has now been removed. 34. Added a number of extra features that are going to be in Perl 5.10. On the whole, these are just syntactic alternatives for features that PCRE had previously implemented using the Python syntax or my own invention. The other formats are all retained for compatibility. (a) Named groups can now be defined as (?...) or (?'name'...) as well as (?P...). The new forms, as well as being in Perl 5.10, are also .NET compatible. (b) A recursion or subroutine call to a named group can now be defined as (?&name) as well as (?P>name). (c) A backreference to a named group can now be defined as \k or \k'name' as well as (?P=name). The new forms, as well as being in Perl 5.10, are also .NET compatible. (d) A conditional reference to a named group can now use the syntax (?() or (?('name') as well as (?(name). (e) A "conditional group" of the form (?(DEFINE)...) can be used to define groups (named and numbered) that are never evaluated inline, but can be called as "subroutines" from elsewhere. In effect, the DEFINE condition is always false. There may be only one alternative in such a group. (f) A test for recursion can be given as (?(R1).. or (?(R&name)... as well as the simple (?(R). The condition is true only if the most recent recursion is that of the given number or name. It does not search out through the entire recursion stack. (g) The escape \gN or \g{N} has been added, where N is a positive or negative number, specifying an absolute or relative reference. 35. Tidied to get rid of some further signed/unsigned compiler warnings and some "unreachable code" warnings. 36. Updated the Unicode property tables to Unicode version 5.0.0. Amongst other things, this adds five new scripts. 37. Perl ignores orphaned \E escapes completely. PCRE now does the same. There were also incompatibilities regarding the handling of \Q..\E inside character classes, for example with patterns like [\Qa\E-\Qz\E] where the hyphen was adjacent to \Q or \E. I hope I've cleared all this up now. 38. Like Perl, PCRE detects when an indefinitely repeated parenthesized group matches an empty string, and forcibly breaks the loop. There were bugs in this code in non-simple cases. For a pattern such as ^(a()*)* matched against aaaa the result was just "a" rather than "aaaa", for example. Two separate and independent bugs (that affected different cases) have been fixed. 39. Refactored the code to abolish the use of different opcodes for small capturing bracket numbers. This is a tidy that I avoided doing when I removed the limit on the number of capturing brackets for 3.5 back in 2001. The new approach is not only tidier, it makes it possible to reduce the memory needed to fix the previous bug (38). 40. Implemented PCRE_NEWLINE_ANY to recognize any of the Unicode newline sequences (http://unicode.org/unicode/reports/tr18/) as "newline" when processing dot, circumflex, or dollar metacharacters, or #-comments in /x mode. 41. Add \R to match any Unicode newline sequence, as suggested in the Unicode report. 42. Applied patch, originally from Ari Pollak, modified by Google, to allow copy construction and assignment in the C++ wrapper. 43. Updated pcregrep to support "--newline=any". In the process, I fixed a couple of bugs that could have given wrong results in the "--newline=crlf" case. 44. Added a number of casts and did some reorganization of signed/unsigned int variables following suggestions from Dair Grant. Also renamed the variable "this" as "item" because it is a C++ keyword. 45. Arranged for dftables to add #include "pcre_internal.h" to pcre_chartables.c because without it, gcc 4.x may remove the array definition from the final binary if PCRE is built into a static library and dead code stripping is activated. 46. For an unanchored pattern, if a match attempt fails at the start of a newline sequence, and the newline setting is CRLF or ANY, and the next two characters are CRLF, advance by two characters instead of one. 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 in a data line sets the "match limit" value \Q in a data line sets the "match recursion limt" value -S sets the stack size, where is in megabytes The -S option isn't available for Windows. Version 6.6 06-Feb-06 --------------------- 1. Change 16(a) for 6.5 broke things, because PCRE_DATA_SCOPE was not defined in pcreposix.h. I have copied the definition from pcre.h. 2. Change 25 for 6.5 broke compilation in a build directory out-of-tree because pcre.h is no longer a built file. 3. Added Jeff Friedl's additional debugging patches to pcregrep. These are not normally included in the compiled code. Version 6.5 01-Feb-06 --------------------- 1. When using the partial match feature with pcre_dfa_exec(), it was not anchoring the second and subsequent partial matches at the new starting point. This could lead to incorrect results. For example, with the pattern /1234/, partially matching against "123" and then "a4" gave a match. 2. Changes to pcregrep: (a) All non-match returns from pcre_exec() were being treated as failures to match the line. Now, unless the error is PCRE_ERROR_NOMATCH, an error message is output. Some extra information is given for the PCRE_ERROR_MATCHLIMIT and PCRE_ERROR_RECURSIONLIMIT errors, which are probably the only errors that are likely to be caused by users (by specifying a regex that has nested indefinite repeats, for instance). If there are more than 20 of these errors, pcregrep is abandoned. (b) A binary zero was treated as data while matching, but terminated the output line if it was written out. This has been fixed: binary zeroes are now no different to any other data bytes. (c) Whichever of the LC_ALL or LC_CTYPE environment variables is set is used to set a locale for matching. The --locale=xxxx long option has been added (no short equivalent) to specify a locale explicitly on the pcregrep command, overriding the environment variables. (d) When -B was used with -n, some line numbers in the output were one less than they should have been. (e) Added the -o (--only-matching) option. (f) If -A or -C was used with -c (count only), some lines of context were accidentally printed for the final match. (g) Added the -H (--with-filename) option. (h) The combination of options -rh failed to suppress file names for files that were found from directory arguments. (i) Added the -D (--devices) and -d (--directories) options. (j) Added the -F (--fixed-strings) option. (k) Allow "-" to be used as a file name for -f as well as for a data file. (l) Added the --colo(u)r option. (m) Added Jeffrey Friedl's -S testing option, but within #ifdefs so that it is not present by default. 3. A nasty bug was discovered in the handling of recursive patterns, that is, items such as (?R) or (?1), when the recursion could match a number of alternatives. If it matched one of the alternatives, but subsequently, outside the recursion, there was a failure, the code tried to back up into the recursion. However, because of the way PCRE is implemented, this is not possible, and the result was an incorrect result from the match. In order to prevent this happening, the specification of recursion has been changed so that all such subpatterns are automatically treated as atomic groups. Thus, for example, (?R) is treated as if it were (?>(?R)). 4. I had overlooked the fact that, in some locales, there are characters for which isalpha() is true but neither isupper() nor islower() are true. In the fr_FR locale, for instance, the \xAA and \xBA characters (ordmasculine and ordfeminine) are like this. This affected the treatment of \w and \W when they appeared in character classes, but not when they appeared outside a character class. The bit map for "word" characters is now created separately from the results of isalnum() instead of just taking it from the upper, lower, and digit maps. (Plus the underscore character, of course.) 5. The above bug also affected the handling of POSIX character classes such as [[:alpha:]] and [[:alnum:]]. These do not have their own bit maps in PCRE's permanent tables. Instead, the bit maps for such a class were previously created as the appropriate unions of the upper, lower, and digit bitmaps. Now they are created by subtraction from the [[:word:]] class, which has its own bitmap. 6. The [[:blank:]] character class matches horizontal, but not vertical space. It is created by subtracting the vertical space characters (\x09, \x0a, \x0b, \x0c) from the [[:space:]] bitmap. Previously, however, the subtraction was done in the overall bitmap for a character class, meaning that a class such as [\x0c[:blank:]] was incorrect because \x0c would not be recognized. This bug has been fixed. 7. Patches from the folks at Google: (a) pcrecpp.cc: "to handle a corner case that may or may not happen in real life, but is still worth protecting against". (b) pcrecpp.cc: "corrects a bug when negative radixes are used with regular expressions". (c) pcre_scanner.cc: avoid use of std::count() because not all systems have it. (d) Split off pcrecpparg.h from pcrecpp.h and had the former built by "configure" and the latter not, in order to fix a problem somebody had with compiling the Arg class on HP-UX. (e) Improve the error-handling of the C++ wrapper a little bit. (f) New tests for checking recursion limiting. 8. The pcre_memmove() function, which is used only if the environment does not have a standard memmove() function (and is therefore rarely compiled), contained two bugs: (a) use of int instead of size_t, and (b) it was not returning a result (though PCRE never actually uses the result). 9. In the POSIX regexec() interface, if nmatch is specified as a ridiculously large number - greater than INT_MAX/(3*sizeof(int)) - REG_ESPACE is returned instead of calling malloc() with an overflowing number that would most likely cause subsequent chaos. 10. The debugging option of pcretest was not showing the NO_AUTO_CAPTURE flag. 11. The POSIX flag REG_NOSUB is now supported. When a pattern that was compiled with this option is matched, the nmatch and pmatch options of regexec() are ignored. 12. Added REG_UTF8 to the POSIX interface. This is not defined by POSIX, but is provided in case anyone wants to the the POSIX interface with UTF-8 strings. 13. Added CXXLDFLAGS to the Makefile parameters to provide settings only on the C++ linking (needed for some HP-UX environments). 14. Avoid compiler warnings in get_ucpname() when compiled without UCP support (unused parameter) and in the pcre_printint() function (omitted "default" switch label when the default is to do nothing). 15. Added some code to make it possible, when PCRE is compiled as a C++ library, to replace subject pointers for pcre_exec() with a smart pointer class, thus making it possible to process discontinuous strings. 16. The two macros PCRE_EXPORT and PCRE_DATA_SCOPE are confusing, and perform much the same function. They were added by different people who were trying to make PCRE easy to compile on non-Unix systems. It has been suggested that PCRE_EXPORT be abolished now that there is more automatic apparatus for compiling on Windows systems. I have therefore replaced it with PCRE_DATA_SCOPE. This is set automatically for Windows; if not set it defaults to "extern" for C or "extern C" for C++, which works fine on Unix-like systems. It is now possible to override the value of PCRE_DATA_ SCOPE with something explicit in config.h. In addition: (a) pcreposix.h still had just "extern" instead of either of these macros; I have replaced it with PCRE_DATA_SCOPE. (b) Functions such as _pcre_xclass(), which are internal to the library, but external in the C sense, all had PCRE_EXPORT in their definitions. This is apparently wrong for the Windows case, so I have removed it. (It makes no difference on Unix-like systems.) 17. Added a new limit, MATCH_LIMIT_RECURSION, which limits the depth of nesting of recursive calls to match(). This is different to MATCH_LIMIT because that limits the total number of calls to match(), not all of which increase the depth of recursion. Limiting the recursion depth limits the amount of stack (or heap if NO_RECURSE is set) that is used. The default can be set when PCRE is compiled, and changed at run time. A patch from Google adds this functionality to the C++ interface. 18. Changes to the handling of Unicode character properties: (a) Updated the table to Unicode 4.1.0. (b) Recognize characters that are not in the table as "Cn" (undefined). (c) I revised the way the table is implemented to a much improved format which includes recognition of ranges. It now supports the ranges that are defined in UnicodeData.txt, and it also amalgamates other characters into ranges. This has reduced the number of entries in the table from around 16,000 to around 3,000, thus reducing its size considerably. I realized I did not need to use a tree structure after all - a binary chop search is just as efficient. Having reduced the number of entries, I extended their size from 6 bytes to 8 bytes to allow for more data. (d) Added support for Unicode script names via properties such as \p{Han}. 19. In UTF-8 mode, a backslash followed by a non-Ascii character was not matching that character. 20. When matching a repeated Unicode property with a minimum greater than zero, (for example \pL{2,}), PCRE could look past the end of the subject if it reached it while seeking the minimum number of characters. This could happen only if some of the characters were more than one byte long, because there is a check for at least the minimum number of bytes. 21. Refactored the implementation of \p and \P so as to be more general, to allow for more different types of property in future. This has changed the compiled form incompatibly. Anybody with saved compiled patterns that use \p or \P will have to recompile them. 22. Added "Any" and "L&" to the supported property types. 23. Recognize \x{...} as a code point specifier, even when not in UTF-8 mode, but give a compile time error if the value is greater than 0xff. 24. The man pages for pcrepartial, pcreprecompile, and pcre_compile2 were accidentally not being installed or uninstalled. 25. The pcre.h file was built from pcre.h.in, but the only changes that were made were to insert the current release number. This seemed silly, because it made things harder for people building PCRE on systems that don't run "configure". I have turned pcre.h into a distributed file, no longer built by "configure", with the version identification directly included. There is no longer a pcre.h.in file. However, this change necessitated a change to the pcre-config script as well. It is built from pcre-config.in, and one of the substitutions was the release number. I have updated configure.ac so that ./configure now finds the release number by grepping pcre.h. 26. Added the ability to run the tests under valgrind. Version 6.4 05-Sep-05 --------------------- 1. Change 6.0/10/(l) to pcregrep introduced a bug that caused separator lines "--" to be printed when multiple files were scanned, even when none of the -A, -B, or -C options were used. This is not compatible with Gnu grep, so I consider it to be a bug, and have restored the previous behaviour. 2. A couple of code tidies to get rid of compiler warnings. 3. The pcretest program used to cheat by referring to symbols in the library whose names begin with _pcre_. These are internal symbols that are not really supposed to be visible externally, and in some environments it is possible to suppress them. The cheating is now confined to including certain files from the library's source, which is a bit cleaner. 4. Renamed pcre.in as pcre.h.in to go with pcrecpp.h.in; it also makes the file's purpose clearer. 5. Reorganized pcre_ucp_findchar(). Version 6.3 15-Aug-05 --------------------- 1. The file libpcre.pc.in did not have general read permission in the tarball. 2. There were some problems when building without C++ support: (a) If C++ support was not built, "make install" and "make test" still tried to test it. (b) There were problems when the value of CXX was explicitly set. Some changes have been made to try to fix these, and ... (c) --disable-cpp can now be used to explicitly disable C++ support. (d) The use of @CPP_OBJ@ directly caused a blank line preceded by a backslash in a target when C++ was disabled. This confuses some versions of "make", apparently. Using an intermediate variable solves this. (Same for CPP_LOBJ.) 3. $(LINK_FOR_BUILD) now includes $(CFLAGS_FOR_BUILD) and $(LINK) (non-Windows) now includes $(CFLAGS) because these flags are sometimes necessary on certain architectures. 4. Added a setting of -export-symbols-regex to the link command to remove those symbols that are exported in the C sense, but actually are local within the library, and not documented. Their names all begin with "_pcre_". This is not a perfect job, because (a) we have to except some symbols that pcretest ("illegally") uses, and (b) the facility isn't always available (and never for static libraries). I have made a note to try to find a way round (a) in the future. Version 6.2 01-Aug-05 --------------------- 1. There was no test for integer overflow of quantifier values. A construction such as {1111111111111111} would give undefined results. What is worse, if a minimum quantifier for a parenthesized subpattern overflowed and became negative, the calculation of the memory size went wrong. This could have led to memory overwriting. 2. Building PCRE using VPATH was broken. Hopefully it is now fixed. 3. Added "b" to the 2nd argument of fopen() in dftables.c, for non-Unix-like operating environments where this matters. 4. Applied Giuseppe Maxia's patch to add additional features for controlling PCRE options from within the C++ wrapper. 5. Named capturing subpatterns were not being correctly counted when a pattern was compiled. This caused two problems: (a) If there were more than 100 such subpatterns, the calculation of the memory needed for the whole compiled pattern went wrong, leading to an overflow error. (b) Numerical back references of the form \12, where the number was greater than 9, were not recognized as back references, even though there were sufficient previous subpatterns. 6. Two minor patches to pcrecpp.cc in order to allow it to compile on older versions of gcc, e.g. 2.95.4. Version 6.1 21-Jun-05 --------------------- 1. There was one reference to the variable "posix" in pcretest.c that was not surrounded by "#if !defined NOPOSIX". 2. Make it possible to compile pcretest without DFA support, UTF8 support, or the cross-check on the old pcre_info() function, for the benefit of the cut-down version of PCRE that is currently imported into Exim. 3. A (silly) pattern starting with (?i)(?-i) caused an internal space allocation error. I've done the easy fix, which wastes 2 bytes for sensible patterns that start (?i) but I don't think that matters. The use of (?i) is just an example; this all applies to the other options as well. 4. Since libtool seems to echo the compile commands it is issuing, the output from "make" can be reduced a bit by putting "@" in front of each libtool compile command. 5. Patch from the folks at Google for configure.in to be a bit more thorough in checking for a suitable C++ installation before trying to compile the C++ stuff. This should fix a reported problem when a compiler was present, but no suitable headers. 6. The man pages all had just "PCRE" as their title. I have changed them to be the relevant file name. I have also arranged that these names are retained in the file doc/pcre.txt, which is a concatenation in text format of all the man pages except the little individual ones for each function. 7. The NON-UNIX-USE file had not been updated for the different set of source files that come with release 6. I also added a few comments about the C++ wrapper. Version 6.0 07-Jun-05 --------------------- 1. Some minor internal re-organization to help with my DFA experiments. 2. Some missing #ifdef SUPPORT_UCP conditionals in pcretest and printint that didn't matter for the library itself when fully configured, but did matter when compiling without UCP support, or within Exim, where the ucp files are not imported. 3. Refactoring of the library code to split up the various functions into different source modules. The addition of the new DFA matching code (see below) to a single monolithic source would have made it really too unwieldy, quite apart from causing all the code to be include in a statically linked application, when only some functions are used. This is relevant even without the DFA addition now that patterns can be compiled in one application and matched in another. The downside of splitting up is that there have to be some external functions and data tables that are used internally in different modules of the library but which are not part of the API. These have all had their names changed to start with "_pcre_" so that they are unlikely to clash with other external names. 4. Added an alternate matching function, pcre_dfa_exec(), which matches using a different (DFA) algorithm. Although it is slower than the original function, it does have some advantages for certain types of matching problem. 5. Upgrades to pcretest in order to test the features of pcre_dfa_exec(), including restarting after a partial match. 6. A patch for pcregrep that defines INVALID_FILE_ATTRIBUTES if it is not defined when compiling for Windows was sent to me. I have put it into the code, though I have no means of testing or verifying it. 7. Added the pcre_refcount() auxiliary function. 8. Added the PCRE_FIRSTLINE option. This constrains an unanchored pattern to match before or at the first newline in the subject string. In pcretest, the /f option on a pattern can be used to set this. 9. A repeated \w when used in UTF-8 mode with characters greater than 256 would behave wrongly. This has been present in PCRE since release 4.0. 10. A number of changes to the pcregrep command: (a) Refactored how -x works; insert ^(...)$ instead of setting PCRE_ANCHORED and checking the length, in preparation for adding something similar for -w. (b) Added the -w (match as a word) option. (c) Refactored the way lines are read and buffered so as to have more than one at a time available. (d) Implemented a pcregrep test script. (e) Added the -M (multiline match) option. This allows patterns to match over several lines of the subject. The buffering ensures that at least 8K, or the rest of the document (whichever is the shorter) is available for matching (and similarly the previous 8K for lookbehind assertions). (f) Changed the --help output so that it now says -w, --word-regex(p) instead of two lines, one with "regex" and the other with "regexp" because that confused at least one person since the short forms are the same. (This required a bit of code, as the output is generated automatically from a table. It wasn't just a text change.) (g) -- can be used to terminate pcregrep options if the next thing isn't an option but starts with a hyphen. Could be a pattern or a path name starting with a hyphen, for instance. (h) "-" can be given as a file name to represent stdin. (i) When file names are being printed, "(standard input)" is used for the standard input, for compatibility with GNU grep. Previously "" was used. (j) The option --label=xxx can be used to supply a name to be used for stdin when file names are being printed. There is no short form. (k) Re-factored the options decoding logic because we are going to add two more options that take data. Such options can now be given in four different ways, e.g. "-fname", "-f name", "--file=name", "--file name". (l) Added the -A, -B, and -C options for requesting that lines of context around matches be printed. (m) Added the -L option to print the names of files that do not contain any matching lines, that is, the complement of -l. (n) The return code is 2 if any file cannot be opened, but pcregrep does continue to scan other files. (o) The -s option was incorrectly implemented. For compatibility with other greps, it now suppresses the error message for a non-existent or non- accessible file (but not the return code). There is a new option called -q that suppresses the output of matching lines, which was what -s was previously doing. (p) Added --include and --exclude options to specify files for inclusion and exclusion when recursing. 11. The Makefile was not using the Autoconf-supported LDFLAGS macro properly. Hopefully, it now does. 12. Missing cast in pcre_study(). 13. Added an "uninstall" target to the makefile. 14. Replaced "extern" in the function prototypes in Makefile.in with "PCRE_DATA_SCOPE", which defaults to 'extern' or 'extern "C"' in the Unix world, but is set differently for Windows. 15. Added a second compiling function called pcre_compile2(). The only difference is that it has an extra argument, which is a pointer to an integer error code. When there is a compile-time failure, this is set non-zero, in addition to the error test pointer being set to point to an error message. The new argument may be NULL if no error number is required (but then you may as well call pcre_compile(), which is now just a wrapper). This facility is provided because some applications need a numeric error indication, but it has also enabled me to tidy up the way compile-time errors are handled in the POSIX wrapper. 16. Added VPATH=.libs to the makefile; this should help when building with one prefix path and installing with another. (Or so I'm told by someone who knows more about this stuff than I do.) 17. Added a new option, REG_DOTALL, to the POSIX function regcomp(). This passes PCRE_DOTALL to the pcre_compile() function, making the "." character match everything, including newlines. This is not POSIX-compatible, but somebody wanted the feature. From pcretest it can be activated by using both the P and the s flags. 18. AC_PROG_LIBTOOL appeared twice in Makefile.in. Removed one. 19. libpcre.pc was being incorrectly installed as executable. 20. A couple of places in pcretest check for end-of-line by looking for '\n'; it now also looks for '\r' so that it will work unmodified on Windows. 21. Added Google's contributed C++ wrapper to the distribution. 22. Added some untidy missing memory free() calls in pcretest, to keep Electric Fence happy when testing. Version 5.0 13-Sep-04 --------------------- 1. Internal change: literal characters are no longer packed up into items containing multiple characters in a single byte-string. Each character is now matched using a separate opcode. However, there may be more than one byte in the character in UTF-8 mode. 2. The pcre_callout_block structure has two new fields: pattern_position and next_item_length. These contain the offset in the pattern to the next match item, and its length, respectively. 3. The PCRE_AUTO_CALLOUT option for pcre_compile() requests the automatic insertion of callouts before each pattern item. Added the /C option to pcretest to make use of this. 4. On the advice of a Windows user, the lines #if defined(_WIN32) || defined(WIN32) _setmode( _fileno( stdout ), 0x8000 ); #endif /* defined(_WIN32) || defined(WIN32) */ have been added to the source of pcretest. This apparently does useful magic in relation to line terminators. 5. Changed "r" and "w" in the calls to fopen() in pcretest to "rb" and "wb" for the benefit of those environments where the "b" makes a difference. 6. The icc compiler has the same options as gcc, but "configure" doesn't seem to know about it. I have put a hack into configure.in that adds in code to set GCC=yes if CC=icc. This seems to end up at a point in the generated configure script that is early enough to affect the setting of compiler options, which is what is needed, but I have no means of testing whether it really works. (The user who reported this had patched the generated configure script, which of course I cannot do.) LATER: After change 22 below (new libtool files), the configure script seems to know about icc (and also ecc). Therefore, I have commented out this hack in configure.in. 7. Added support for pkg-config (2 patches were sent in). 8. Negated POSIX character classes that used a combination of internal tables were completely broken. These were [[:^alpha:]], [[:^alnum:]], and [[:^ascii]]. Typically, they would match almost any characters. The other POSIX classes were not broken in this way. 9. Matching the pattern "\b.*?" against "ab cd", starting at offset 1, failed to find the match, as PCRE was deluded into thinking that the match had to start at the start point or following a newline. The same bug applied to patterns with negative forward assertions or any backward assertions preceding ".*" at the start, unless the pattern required a fixed first character. This was a failing pattern: "(?!.bcd).*". The bug is now fixed. 10. In UTF-8 mode, when moving forwards in the subject after a failed match starting at the last subject character, bytes beyond the end of the subject string were read. 11. Renamed the variable "class" as "classbits" to make life easier for C++ users. (Previously there was a macro definition, but it apparently wasn't enough.) 12. Added the new field "tables" to the extra data so that tables can be passed in at exec time, or the internal tables can be re-selected. This allows a compiled regex to be saved and re-used at a later time by a different program that might have everything at different addresses. 13. Modified the pcre-config script so that, when run on Solaris, it shows a -R library as well as a -L library. 14. The debugging options of pcretest (-d on the command line or D on a pattern) showed incorrect output for anything following an extended class that contained multibyte characters and which was followed by a quantifier. 15. Added optional support for general category Unicode character properties via the \p, \P, and \X escapes. Unicode property support implies UTF-8 support. It adds about 90K to the size of the library. The meanings of the inbuilt class escapes such as \d and \s have NOT been changed. 16. Updated pcredemo.c to include calls to free() to release the memory for the compiled pattern. 17. The generated file chartables.c was being created in the source directory instead of in the building directory. This caused the build to fail if the source directory was different from the building directory, and was read-only. 18. Added some sample Win commands from Mark Tetrode into the NON-UNIX-USE file. No doubt somebody will tell me if they don't make sense... Also added Dan Mooney's comments about building on OpenVMS. 19. Added support for partial matching via the PCRE_PARTIAL option for pcre_exec() and the \P data escape in pcretest. 20. Extended pcretest with 3 new pattern features: (i) A pattern option of the form ">rest-of-line" causes pcretest to write the compiled pattern to the file whose name is "rest-of-line". This is a straight binary dump of the data, with the saved pointer to the character tables forced to be NULL. The study data, if any, is written too. After writing, pcretest reads a new pattern. (ii) If, instead of a pattern, ": new target : new target : use native compiler : use native linker : handle Windows platform correctly : ditto : ditto copy DLL to top builddir before testing As part of these changes, -no-undefined was removed again. This was reported to give trouble on HP-UX 11.0, so getting rid of it seems like a good idea in any case. 3. Some tidies to get rid of compiler warnings: . In the match_data structure, match_limit was an unsigned long int, whereas match_call_count was an int. I've made them both unsigned long ints. . In pcretest the fact that a const uschar * doesn't automatically cast to a void * provoked a warning. . Turning on some more compiler warnings threw up some "shadow" variables and a few more missing casts. 4. If PCRE was complied with UTF-8 support, but called without the PCRE_UTF8 option, a class that contained a single character with a value between 128 and 255 (e.g. /[\xFF]/) caused PCRE to crash. 5. If PCRE was compiled with UTF-8 support, but called without the PCRE_UTF8 option, a class that contained several characters, but with at least one whose value was between 128 and 255 caused PCRE to crash. Version 4.1 12-Mar-03 --------------------- 1. Compiling with gcc -pedantic found a couple of places where casts were needed, and a string in dftables.c that was longer than standard compilers are required to support. 2. Compiling with Sun's compiler found a few more places where the code could be tidied up in order to avoid warnings. 3. The variables for cross-compiling were called HOST_CC and HOST_CFLAGS; the first of these names is deprecated in the latest Autoconf in favour of the name CC_FOR_BUILD, because "host" is typically used to mean the system on which the compiled code will be run. I can't find a reference for HOST_CFLAGS, but by analogy I have changed it to CFLAGS_FOR_BUILD. 4. Added -no-undefined to the linking command in the Makefile, because this is apparently helpful for Windows. To make it work, also added "-L. -lpcre" to the linking step for the pcreposix library. 5. PCRE was failing to diagnose the case of two named groups with the same name. 6. A problem with one of PCRE's optimizations was discovered. PCRE remembers a literal character that is needed in the subject for a match, and scans along to ensure that it is present before embarking on the full matching process. This saves time in cases of nested unlimited repeats that are never going to match. Problem: the scan can take a lot of time if the subject is very long (e.g. megabytes), thus penalizing straightforward matches. It is now done only if the amount of subject to be scanned is less than 1000 bytes. 7. A lesser problem with the same optimization is that it was recording the first character of an anchored pattern as "needed", thus provoking a search right along the subject, even when the first match of the pattern was going to fail. The "needed" character is now not set for anchored patterns, unless it follows something in the pattern that is of non-fixed length. Thus, it still fulfils its original purpose of finding quick non-matches in cases of nested unlimited repeats, but isn't used for simple anchored patterns such as /^abc/. Version 4.0 17-Feb-03 --------------------- 1. If a comment in an extended regex that started immediately after a meta-item extended to the end of string, PCRE compiled incorrect data. This could lead to all kinds of weird effects. Example: /#/ was bad; /()#/ was bad; /a#/ was not. 2. Moved to autoconf 2.53 and libtool 1.4.2. 3. Perl 5.8 no longer needs "use utf8" for doing UTF-8 things. Consequently, the special perltest8 script is no longer needed - all the tests can be run from a single perltest script. 4. From 5.004, Perl has not included the VT character (0x0b) in the set defined by \s. It has now been removed in PCRE. This means it isn't recognized as whitespace in /x regexes too, which is the same as Perl. Note that the POSIX class [:space:] *does* include VT, thereby creating a mess. 5. Added the class [:blank:] (a GNU extension from Perl 5.8) to match only space and tab. 6. Perl 5.005 was a long time ago. It's time to amalgamate the tests that use its new features into the main test script, reducing the number of scripts. 7. Perl 5.8 has changed the meaning of patterns like /a(?i)b/. Earlier versions were backward compatible, and made the (?i) apply to the whole pattern, as if /i were given. Now it behaves more logically, and applies the option setting only to what follows. PCRE has been changed to follow suit. However, if it finds options settings right at the start of the pattern, it extracts them into the global options, as before. Thus, they show up in the info data. 8. Added support for the \Q...\E escape sequence. Characters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they will cause variable interpolation. Note the following examples: Pattern PCRE matches Perl matches \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz \Qabc\$xyz\E abc\$xyz abc\$xyz \Qabc\E\$\Qxyz\E abc$xyz abc$xyz For compatibility with Perl, \Q...\E sequences are recognized inside character classes as well as outside them. 9. Re-organized 3 code statements in pcretest to avoid "overflow in floating-point constant arithmetic" warnings from a Microsoft compiler. Added a (size_t) cast to one statement in pcretest and one in pcreposix to avoid signed/unsigned warnings. 10. SunOS4 doesn't have strtoul(). This was used only for unpicking the -o option for pcretest, so I've replaced it by a simple function that does just that job. 11. pcregrep was ending with code 0 instead of 2 for the commands "pcregrep" or "pcregrep -". 12. Added "possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java package. This provides some syntactic sugar for simple cases of what my documentation calls "once-only subpatterns". A pattern such as x*+ is the same as (?>x*). In other words, if what is inside (?>...) is just a single repeated item, you can use this simplified notation. Note that only makes sense with greedy quantifiers. Consequently, the use of the possessive quantifier forces greediness, whatever the setting of the PCRE_UNGREEDY option. 13. A change of greediness default within a pattern was not taking effect at the current level for patterns like /(b+(?U)a+)/. It did apply to parenthesized subpatterns that followed. Patterns like /b+(?U)a+/ worked because the option was abstracted outside. 14. PCRE now supports the \G assertion. It is true when the current matching position is at the start point of the match. This differs from \A when the starting offset is non-zero. Used with the /g option of pcretest (or similar code), it works in the same way as it does for Perl's /g option. If all alternatives of a regex begin with \G, the expression is anchored to the start match position, and the "anchored" flag is set in the compiled expression. 15. Some bugs concerning the handling of certain option changes within patterns have been fixed. These applied to options other than (?ims). For example, "a(?x: b c )d" did not match "XabcdY" but did match "Xa b c dY". It should have been the other way round. Some of this was related to change 7 above. 16. PCRE now gives errors for /[.x.]/ and /[=x=]/ as unsupported POSIX features, as Perl does. Previously, PCRE gave the warnings only for /[[.x.]]/ and /[[=x=]]/. PCRE now also gives an error for /[:name:]/ because it supports POSIX classes only within a class (e.g. /[[:alpha:]]/). 17. Added support for Perl's \C escape. This matches one byte, even in UTF8 mode. Unlike ".", it always matches newline, whatever the setting of PCRE_DOTALL. However, PCRE does not permit \C to appear in lookbehind assertions. Perl allows it, but it doesn't (in general) work because it can't calculate the length of the lookbehind. At least, that's the case for Perl 5.8.0 - I've been told they are going to document that it doesn't work in future. 18. Added an error diagnosis for escapes that PCRE does not support: these are \L, \l, \N, \P, \p, \U, \u, and \X. 19. Although correctly diagnosing a missing ']' in a character class, PCRE was reading past the end of the pattern in cases such as /[abcd/. 20. PCRE was getting more memory than necessary for patterns with classes that contained both POSIX named classes and other characters, e.g. /[[:space:]abc/. 21. Added some code, conditional on #ifdef VPCOMPAT, to make life easier for compiling PCRE for use with Virtual Pascal. 22. Small fix to the Makefile to make it work properly if the build is done outside the source tree. 23. Added a new extension: a condition to go with recursion. If a conditional subpattern starts with (?(R) the "true" branch is used if recursion has happened, whereas the "false" branch is used only at the top level. 24. When there was a very long string of literal characters (over 255 bytes without UTF support, over 250 bytes with UTF support), the computation of how much memory was required could be incorrect, leading to segfaults or other strange effects. 25. PCRE was incorrectly assuming anchoring (either to start of subject or to start of line for a non-DOTALL pattern) when a pattern started with (.*) and there was a subsequent back reference to those brackets. This meant that, for example, /(.*)\d+\1/ failed to match "abc123bc". Unfortunately, it isn't possible to check for precisely this case. All we can do is abandon the optimization if .* occurs inside capturing brackets when there are any back references whatsoever. (See below for a better fix that came later.) 26. The handling of the optimization for finding the first character of a non-anchored pattern, and for finding a character that is required later in the match were failing in some cases. This didn't break the matching; it just failed to optimize when it could. The way this is done has been re-implemented. 27. Fixed typo in error message for invalid (?R item (it said "(?p"). 28. Added a new feature that provides some of the functionality that Perl provides with (?{...}). The facility is termed a "callout". The way it is done in PCRE is for the caller to provide an optional function, by setting pcre_callout to its entry point. Like pcre_malloc and pcre_free, this is a global variable. By default it is unset, which disables all calling out. To get the function called, the regex must include (?C) at appropriate points. This is, in fact, equivalent to (?C0), and any number <= 255 may be given with (?C). This provides a means of identifying different callout points. When PCRE reaches such a point in the regex, if pcre_callout has been set, the external function is called. It is provided with data in a structure called pcre_callout_block, which is defined in pcre.h. If the function returns 0, matching continues; if it returns a non-zero value, the match at the current point fails. However, backtracking will occur if possible. [This was changed later and other features added - see item 49 below.] 29. pcretest is upgraded to test the callout functionality. It provides a callout function that displays information. By default, it shows the start of the match and the current position in the text. There are some new data escapes to vary what happens: \C+ in addition, show current contents of captured substrings \C- do not supply a callout function \C!n return 1 when callout number n is reached \C!n!m return 1 when callout number n is reached for the mth time 30. If pcregrep was called with the -l option and just a single file name, it output "" if a match was found, instead of the file name. 31. Improve the efficiency of the POSIX API to PCRE. If the number of capturing slots is less than POSIX_MALLOC_THRESHOLD, use a block on the stack to pass to pcre_exec(). This saves a malloc/free per call. The default value of POSIX_MALLOC_THRESHOLD is 10; it can be changed by --with-posix-malloc-threshold when configuring. 32. The default maximum size of a compiled pattern is 64K. There have been a few cases of people hitting this limit. The code now uses macros to handle the storing of links as offsets within the compiled pattern. It defaults to 2-byte links, but this can be changed to 3 or 4 bytes by --with-link-size when configuring. Tests 2 and 5 work only with 2-byte links because they output debugging information about compiled patterns. 33. Internal code re-arrangements: (a) Moved the debugging function for printing out a compiled regex into its own source file (printint.c) and used #include to pull it into pcretest.c and, when DEBUG is defined, into pcre.c, instead of having two separate copies. (b) Defined the list of op-code names for debugging as a macro in internal.h so that it is next to the definition of the opcodes. (c) Defined a table of op-code lengths for simpler skipping along compiled code. This is again a macro in internal.h so that it is next to the definition of the opcodes. 34. Added support for recursive calls to individual subpatterns, along the lines of Robin Houston's patch (but implemented somewhat differently). 35. Further mods to the Makefile to help Win32. Also, added code to pcregrep to allow it to read and process whole directories in Win32. This code was contributed by Lionel Fourquaux; it has not been tested by me. 36. Added support for named subpatterns. The Python syntax (?P...) is used to name a group. Names consist of alphanumerics and underscores, and must be unique. Back references use the syntax (?P=name) and recursive calls use (?P>name) which is a PCRE extension to the Python extension. Groups still have numbers. The function pcre_fullinfo() can be used after compilation to extract a name/number map. There are three relevant calls: PCRE_INFO_NAMEENTRYSIZE yields the size of each entry in the map PCRE_INFO_NAMECOUNT yields the number of entries PCRE_INFO_NAMETABLE yields a pointer to the map. The map is a vector of fixed-size entries. The size of each entry depends on the length of the longest name used. The first two bytes of each entry are the group number, most significant byte first. There follows the corresponding name, zero terminated. The names are in alphabetical order. 37. Make the maximum literal string in the compiled code 250 for the non-UTF-8 case instead of 255. Making it the same both with and without UTF-8 support means that the same test output works with both. 38. There was a case of malloc(0) in the POSIX testing code in pcretest. Avoid calling malloc() with a zero argument. 39. Change 25 above had to resort to a heavy-handed test for the .* anchoring optimization. I've improved things by keeping a bitmap of backreferences with numbers 1-31 so that if .* occurs inside capturing brackets that are not in fact referenced, the optimization can be applied. It is unlikely that a relevant occurrence of .* (i.e. one which might indicate anchoring or forcing the match to follow \n) will appear inside brackets with a number greater than 31, but if it does, any back reference > 31 suppresses the optimization. 40. Added a new compile-time option PCRE_NO_AUTO_CAPTURE. This has the effect of disabling numbered capturing parentheses. 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 will acquire numbers in the usual way). 41. Redesigned the return codes from the match() function into yes/no/error so that errors can be passed back from deep inside the nested calls. A malloc failure while inside a recursive subpattern call now causes the PCRE_ERROR_NOMEMORY return instead of quietly going wrong. 42. It is now possible to set a limit on the number of times the match() function is called in a call to pcre_exec(). This facility makes it possible to limit the amount of recursion and backtracking, though not in a directly obvious way, because the match() function is used in a number of different circumstances. The count starts from zero for each position in the subject string (for non-anchored patterns). The default limit is, for compatibility, a large number, namely 10 000 000. You can change this in two ways: (a) When configuring PCRE before making, you can use --with-match-limit=n to set a default value for the compiled library. (b) For each call to pcre_exec(), you can pass a pcre_extra block in which a different value is set. See 45 below. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. 43. Added a new function pcre_config(int, void *) to enable run-time extraction of things that can be changed at compile time. The first argument specifies what is wanted and the second points to where the information is to be placed. The current list of available information is: PCRE_CONFIG_UTF8 The output is an integer that is set to one if UTF-8 support is available; otherwise it is set to zero. PCRE_CONFIG_NEWLINE The output is an integer that it set to the value of the code that is used for newline. It is either LF (10) or CR (13). PCRE_CONFIG_LINK_SIZE The output is an integer that contains the number of bytes used for internal linkage in compiled expressions. The value is 2, 3, or 4. See item 32 above. PCRE_CONFIG_POSIX_MALLOC_THRESHOLD The output is an integer that contains the threshold above which the POSIX interface uses malloc() for output vectors. See item 31 above. PCRE_CONFIG_MATCH_LIMIT The output is an unsigned integer that contains the default limit of the number of match() calls in a pcre_exec() execution. See 42 above. 44. pcretest has been upgraded by the addition of the -C option. This causes it to extract all the available output from the new pcre_config() function, and to output it. The program then exits immediately. 45. A need has arisen to pass over additional data with calls to pcre_exec() in order to support additional features. One way would have been to define pcre_exec2() (for example) with extra arguments, but this would not have been extensible, and would also have required all calls to the original function to be mapped to the new one. Instead, I have chosen to extend the mechanism that is used for passing in "extra" data from pcre_study(). The pcre_extra structure is now exposed and defined in pcre.h. It currently contains the following fields: flags a bitmap indicating which of the following fields are set study_data opaque data from pcre_study() match_limit a way of specifying a limit on match() calls for a specific call to pcre_exec() callout_data data for callouts (see 49 below) The flag bits are also defined in pcre.h, and are PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_CALLOUT_DATA The pcre_study() function now returns one of these new pcre_extra blocks, with the actual study data pointed to by the study_data field, and the PCRE_EXTRA_STUDY_DATA flag set. This can be passed directly to pcre_exec() as before. That is, this change is entirely upwards-compatible and requires no change to existing code. If you want to pass in additional data to pcre_exec(), you can either place it in a pcre_extra block provided by pcre_study(), or create your own pcre_extra block. 46. pcretest has been extended to test the PCRE_EXTRA_MATCH_LIMIT feature. If a data string contains the escape sequence \M, pcretest calls pcre_exec() several times with different match limits, until it finds the minimum value needed for pcre_exec() to complete. The value is then output. This can be instructive; for most simple matches the number is quite small, but for pathological cases it gets very large very quickly. 47. There's a new option for pcre_fullinfo() called PCRE_INFO_STUDYSIZE. It returns the size of the data block pointed to by the study_data field in a pcre_extra block, that is, the value that was passed as the argument to pcre_malloc() when PCRE was getting memory in which to place the information created by pcre_study(). The fourth argument should point to a size_t variable. pcretest has been extended so that this information is shown after a successful pcre_study() call when information about the compiled regex is being displayed. 48. Cosmetic change to Makefile: there's no need to have / after $(DESTDIR) because what follows is always an absolute path. (Later: it turns out that this is more than cosmetic for MinGW, because it doesn't like empty path components.) 49. Some changes have been made to the callout feature (see 28 above): (i) A callout function now has three choices for what it returns: 0 => success, carry on matching > 0 => failure at this point, but backtrack if possible < 0 => serious error, return this value from pcre_exec() Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, returning PCRE_ERROR_NOMATCH forces a standard "match failed" error. The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions. It will never be used by PCRE itself. (ii) The pcre_extra structure (see 45 above) has a void * field called callout_data, with corresponding flag bit PCRE_EXTRA_CALLOUT_DATA. The pcre_callout_block structure has a field of the same name. The contents of the field passed in the pcre_extra structure are passed to the callout function in the corresponding field in the callout block. This makes it easier to use the same callout-containing regex from multiple threads. For testing, the pcretest program has a new data escape \C*n pass the number n (may be negative) as callout_data If the callout function in pcretest receives a non-zero value as callout_data, it returns that value. 50. Makefile wasn't handling CFLAGS properly when compiling dftables. Also, there were some redundant $(CFLAGS) in commands that are now specified as $(LINK), which already includes $(CFLAGS). 51. Extensions to UTF-8 support are listed below. These all apply when (a) PCRE has been compiled with UTF-8 support *and* pcre_compile() has been compiled with the PCRE_UTF8 flag. Patterns that are compiled without that flag assume one-byte characters throughout. Note that case-insensitive matching applies only to characters whose values are less than 256. PCRE doesn't support the notion of cases for higher-valued characters. (i) A character class whose characters are all within 0-255 is handled as a bit map, and the map is inverted for negative classes. Previously, a character > 255 always failed to match such a class; however it should match if the class was a negative one (e.g. [^ab]). This has been fixed. (ii) A negated character class with a single character < 255 is coded as "not this character" (OP_NOT). This wasn't working properly when the test character was multibyte, either singly or repeated. (iii) Repeats of multibyte characters are now handled correctly in UTF-8 mode, for example: \x{100}{2,3}. (iv) The character escapes \b, \B, \d, \D, \s, \S, \w, and \W (either singly or repeated) now correctly test multibyte characters. However, PCRE doesn't recognize any characters with values greater than 255 as digits, spaces, or word characters. Such characters always match \D, \S, and \W, and never match \d, \s, or \w. (v) Classes may now contain characters and character ranges with values greater than 255. For example: [ab\x{100}-\x{400}]. (vi) pcregrep now has a --utf-8 option (synonym -u) which makes it call PCRE in UTF-8 mode. 52. The info request value PCRE_INFO_FIRSTCHAR has been renamed PCRE_INFO_FIRSTBYTE because it is a byte value. However, the old name is retained for backwards compatibility. (Note that LASTLITERAL is also a byte value.) 53. The single man page has become too large. I have therefore split it up into a number of separate man pages. These also give rise to individual HTML pages; these are now put in a separate directory, and there is an index.html page that lists them all. Some hyperlinking between the pages has been installed. 54. Added convenience functions for handling named capturing parentheses. 55. Unknown escapes inside character classes (e.g. [\M]) and escapes that aren't interpreted therein (e.g. [\C]) are literals in Perl. This is now also true in PCRE, except when the PCRE_EXTENDED option is set, in which case they are faulted. 56. Introduced HOST_CC and HOST_CFLAGS which can be set in the environment when calling configure. These values are used when compiling the dftables.c program which is run to generate the source of the default character tables. They default to the values of CC and CFLAGS. If you are cross-compiling PCRE, you will need to set these values. 57. Updated the building process for Windows DLL, as provided by Fred Cox. Version 3.9 02-Jan-02 --------------------- 1. A bit of extraneous text had somehow crept into the pcregrep documentation. 2. If --disable-static was given, the building process failed when trying to build pcretest and pcregrep. (For some reason it was using libtool to compile them, which is not right, as they aren't part of the library.) Version 3.8 18-Dec-01 --------------------- 1. The experimental UTF-8 code was completely screwed up. It was packing the bytes in the wrong order. How dumb can you get? Version 3.7 29-Oct-01 --------------------- 1. In updating pcretest to check change 1 of version 3.6, I screwed up. This caused pcretest, when used on the test data, to segfault. Unfortunately, this didn't happen under Solaris 8, where I normally test things. 2. The Makefile had to be changed to make it work on BSD systems, where 'make' doesn't seem to recognize that ./xxx and xxx are the same file. (This entry isn't in ChangeLog distributed with 3.7 because I forgot when I hastily made this fix an hour or so after the initial 3.7 release.) Version 3.6 23-Oct-01 --------------------- 1. Crashed with /(sens|respons)e and \1ibility/ and "sense and sensibility" if offsets passed as NULL with zero offset count. 2. The config.guess and config.sub files had not been updated when I moved to the latest autoconf. Version 3.5 15-Aug-01 --------------------- 1. Added some missing #if !defined NOPOSIX conditionals in pcretest.c that had been forgotten. 2. By using declared but undefined structures, we can avoid using "void" definitions in pcre.h while keeping the internal definitions of the structures private. 3. The distribution is now built using autoconf 2.50 and libtool 1.4. From a user point of view, this means that both static and shared libraries are built by default, but this can be individually controlled. More of the work of handling this static/shared cases is now inside libtool instead of PCRE's make file. 4. The pcretest utility is now installed along with pcregrep because it is useful for users (to test regexs) and by doing this, it automatically gets relinked by libtool. The documentation has been turned into a man page, so there are now .1, .txt, and .html versions in /doc. 5. Upgrades to pcregrep: (i) Added long-form option names like gnu grep. (ii) Added --help to list all options with an explanatory phrase. (iii) Added -r, --recursive to recurse into sub-directories. (iv) Added -f, --file to read patterns from a file. 6. pcre_exec() was referring to its "code" argument before testing that argument for NULL (and giving an error if it was NULL). 7. Upgraded Makefile.in to allow for compiling in a different directory from the source directory. 8. Tiny buglet in pcretest: when pcre_fullinfo() was called to retrieve the options bits, the pointer it was passed was to an int instead of to an unsigned long int. This mattered only on 64-bit systems. 9. Fixed typo (3.4/1) in pcre.h again. Sigh. I had changed pcre.h (which is generated) instead of pcre.in, which it its source. Also made the same change in several of the .c files. 10. A new release of gcc defines printf() as a macro, which broke pcretest because it had an ifdef in the middle of a string argument for printf(). Fixed by using separate calls to printf(). 11. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure script, to force use of CR or LF instead of \n in the source. On non-Unix systems, the value can be set in config.h. 12. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an absolute limit. Changed the text of the error message to make this clear, and likewise updated the man page. 13. The limit of 99 on the number of capturing subpatterns has been removed. The new limit is 65535, which I hope will not be a "real" limit. Version 3.4 22-Aug-00 --------------------- 1. Fixed typo in pcre.h: unsigned const char * changed to const unsigned char *. 2. Diagnose condition (?(0) as an error instead of crashing on matching. Version 3.3 01-Aug-00 --------------------- 1. If an octal character was given, but the value was greater than \377, it was not getting masked to the least significant bits, as documented. This could lead to crashes in some systems. 2. Perl 5.6 (if not earlier versions) accepts classes like [a-\d] and treats the hyphen as a literal. PCRE used to give an error; it now behaves like Perl. 3. Added the functions pcre_free_substring() and pcre_free_substring_list(). These just pass their arguments on to (pcre_free)(), but they are provided because some uses of PCRE bind it to non-C systems that can call its functions, but cannot call free() or pcre_free() directly. 4. Add "make test" as a synonym for "make check". Corrected some comments in the Makefile. 5. Add $(DESTDIR)/ in front of all the paths in the "install" target in the Makefile. 6. Changed the name of pgrep to pcregrep, because Solaris has introduced a command called pgrep for grepping around the active processes. 7. Added the beginnings of support for UTF-8 character strings. 8. Arranged for the Makefile to pass over the settings of CC, CFLAGS, and RANLIB to ./ltconfig so that they are used by libtool. I think these are all the relevant ones. (AR is not passed because ./ltconfig does its own figuring out for the ar command.) 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 --------------------- The only change in this release is the fixing of some bugs in Makefile.in for the "install" target: (1) It was failing to install pcreposix.h. (2) It was overwriting the pcre.3 man page with the pcreposix.3 man page. Version 3.0 01-Feb-00 --------------------- 1. Add support for the /+ modifier to perltest (to output $` like it does in pcretest). 2. Add support for the /g modifier to perltest. 3. Fix pcretest so that it behaves even more like Perl for /g when the pattern matches null strings. 4. Fix perltest so that it doesn't do unwanted things when fed an empty pattern. Perl treats empty patterns specially - it reuses the most recent pattern, which is not what we want. Replace // by /(?#)/ in order to avoid this effect. 5. The POSIX interface was broken in that it was just handing over the POSIX captured string vector to pcre_exec(), but (since release 2.00) PCRE has required a bigger vector, with some working space on the end. This means that the POSIX wrapper now has to get and free some memory, and copy the results. 6. Added some simple autoconf support, placing the test data and the documentation in separate directories, re-organizing some of the information files, and making it build pcre-config (a GNU standard). Also added libtool support for building PCRE as a shared library, which is now the default. 7. Got rid of the leading zero in the definition of PCRE_MINOR because 08 and 09 are not valid octal constants. Single digits will be used for minor values less than 10. 8. Defined REG_EXTENDED and REG_NOSUB as zero in the POSIX header, so that existing programs that set these in the POSIX interface can use PCRE without modification. 9. Added a new function, pcre_fullinfo() with an extensible interface. It can return all that pcre_info() returns, plus additional data. The pcre_info() function is retained for compatibility, but is considered to be obsolete. 10. Added experimental recursion feature (?R) to handle one common case that Perl 5.6 will be able to do with (?p{...}). 11. Added support for POSIX character classes like [:alpha:], which Perl is adopting. Version 2.08 31-Aug-99 ---------------------- 1. When startoffset was not zero and the pattern began with ".*", PCRE was not trying to match at the startoffset position, but instead was moving forward to the next newline as if a previous match had failed. 2. pcretest was not making use of PCRE_NOTEMPTY when repeating for /g and /G, and could get into a loop if a null string was matched other than at the start of the subject. 3. Added definitions of PCRE_MAJOR and PCRE_MINOR to pcre.h so the version can be distinguished at compile time, and for completeness also added PCRE_DATE. 5. Added Paul Sokolovsky's minor changes to make it easy to compile a Win32 DLL in GnuWin32 environments. Version 2.07 29-Jul-99 ---------------------- 1. The documentation is now supplied in plain text form and HTML as well as in the form of man page sources. 2. C++ compilers don't like assigning (void *) values to other pointer types. In particular this affects malloc(). Although there is no problem in Standard C, I've put in casts to keep C++ compilers happy. 3. Typo on pcretest.c; a cast of (unsigned char *) in the POSIX regexec() call should be (const char *). 4. If NOPOSIX is defined, pcretest.c compiles without POSIX support. This may be useful for non-Unix systems who don't want to bother with the POSIX stuff. However, I haven't made this a standard facility. The documentation doesn't mention it, and the Makefile doesn't support it. 5. The Makefile now contains an "install" target, with editable destinations at the top of the file. The pcretest program is not installed. 6. pgrep -V now gives the PCRE version number and date. 7. Fixed bug: a zero repetition after a literal string (e.g. /abcde{0}/) was causing the entire string to be ignored, instead of just the last character. 8. If a pattern like /"([^\\"]+|\\.)*"/ is applied in the normal way to a non-matching string, it can take a very, very long time, even for strings of quite modest length, because of the nested recursion. PCRE now does better in some of these cases. It does this by remembering the last required literal character in the pattern, and pre-searching the subject to ensure it is present before running the real match. In other words, it applies a heuristic to detect some types of certain failure quickly, and in the above example, if presented with a string that has no trailing " it gives "no match" very quickly. 9. A new runtime option PCRE_NOTEMPTY causes null string matches to be ignored; other alternatives are tried instead. Version 2.06 09-Jun-99 ---------------------- 1. Change pcretest's output for amount of store used to show just the code space, because the remainder (the data block) varies in size between 32-bit and 64-bit systems. 2. Added an extra argument to pcre_exec() to supply an offset in the subject to start matching at. This allows lookbehinds to work when searching for multiple occurrences in a string. 3. Added additional options to pcretest for testing multiple occurrences: /+ outputs the rest of the string that follows a match /g loops for multiple occurrences, using the new startoffset argument /G loops for multiple occurrences by passing an incremented pointer 4. PCRE wasn't doing the "first character" optimization for patterns starting with \b or \B, though it was doing it for other lookbehind assertions. That is, it wasn't noticing that a match for a pattern such as /\bxyz/ has to start with the letter 'x'. On long subject strings, this gives a significant speed-up. Version 2.05 21-Apr-99 ---------------------- 1. Changed the type of magic_number from int to long int so that it works properly on 16-bit systems. 2. Fixed a bug which caused patterns starting with .* not to work correctly when the subject string contained newline characters. PCRE was assuming anchoring for such patterns in all cases, which is not correct because .* will not pass a newline unless PCRE_DOTALL is set. It now assumes anchoring only if DOTALL is set at top level; otherwise it knows that patterns starting with .* must be retried after every newline in the subject. Version 2.04 18-Feb-99 ---------------------- 1. For parenthesized subpatterns with repeats whose minimum was zero, the computation of the store needed to hold the pattern was incorrect (too large). If such patterns were nested a few deep, this could multiply and become a real problem. 2. Added /M option to pcretest to show the memory requirement of a specific pattern. Made -m a synonym of -s (which does this globally) for compatibility. 3. Subpatterns of the form (regex){n,m} (i.e. limited maximum) were being compiled in such a way that the backtracking after subsequent failure was pessimal. Something like (a){0,3} was compiled as (a)?(a)?(a)? instead of ((a)((a)(a)?)?)? with disastrous performance if the maximum was of any size. Version 2.03 02-Feb-99 ---------------------- 1. Fixed typo and small mistake in man page. 2. Added 4th condition (GPL supersedes if conflict) and created separate LICENCE file containing the conditions. 3. Updated pcretest so that patterns such as /abc\/def/ work like they do in Perl, that is the internal \ allows the delimiter to be included in the pattern. Locked out the use of \ as a delimiter. If \ immediately follows the final delimiter, add \ to the end of the pattern (to test the error). 4. Added the convenience functions for extracting substrings after a successful match. Updated pcretest to make it able to test these functions. Version 2.02 14-Jan-99 ---------------------- 1. Initialized the working variables associated with each extraction so that their saving and restoring doesn't refer to uninitialized store. 2. Put dummy code into study.c 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. 3. Pcretest: the timing code wasn't using LOOPREPEAT for timing execution calls, and wasn't printing the correct value for compiling calls. Increased the default value of LOOPREPEAT, and the number of significant figures in the times. 4. Changed "/bin/rm" in the Makefile to "-rm" so it works on Windows NT. 5. Renamed "deftables" as "dftables" to get it down to 8 characters, to avoid a building problem on Windows NT with a FAT file system. Version 2.01 21-Oct-98 ---------------------- 1. Changed the API for pcre_compile() to allow for the provision of a pointer to character tables built by pcre_maketables() in the current locale. If NULL is passed, the default tables are used. Version 2.00 24-Sep-98 ---------------------- 1. Since the (>?) facility is in Perl 5.005, don't require PCRE_EXTRA to enable it any more. 2. Allow quantification of (?>) groups, and make it work correctly. 3. The first character computation wasn't working for (?>) groups. 4. Correct the implementation of \Z (it is permitted to match on the \n at the end of the subject) and add 5.005's \z, which really does match only at the very end of the subject. 5. Remove the \X "cut" facility; Perl doesn't have it, and (?> is neater. 6. Remove the ability to specify CASELESS, MULTILINE, DOTALL, and DOLLAR_END_ONLY at runtime, to make it possible to implement the Perl 5.005 localized options. All options to pcre_study() were also removed. 7. Add other new features from 5.005: $(?<= positive lookbehind $(?a*))*/ (a PCRE_EXTRA facility). Version 1.00 18-Nov-97 ---------------------- 1. Added compile-time macros to support systems such as SunOS4 which don't have memmove() or strerror() but have other things that can be used instead. 2. Arranged that "make clean" removes the executables. Version 0.99 27-Oct-97 ---------------------- 1. Fixed bug in code for optimizing classes with only one character. It was initializing a 32-byte map regardless, which could cause it to run off the end of the memory it had got. 2. Added, conditional on PCRE_EXTRA, the proposed (?>REGEX) construction. Version 0.98 22-Oct-97 ---------------------- 1. Fixed bug in code for handling temporary memory usage when there are more back references than supplied space in the ovector. This could cause segfaults. Version 0.97 21-Oct-97 ---------------------- 1. Added the \X "cut" facility, conditional on PCRE_EXTRA. 2. Optimized negated single characters not to use a bit map. 3. Brought error texts together as macro definitions; clarified some of them; fixed one that was wrong - it said "range out of order" when it meant "invalid escape sequence". 4. Changed some char * arguments to const char *. 5. Added PCRE_NOTBOL and PCRE_NOTEOL (from POSIX). 6. Added the POSIX-style API wrapper in pcreposix.a and testing facilities in pcretest. Version 0.96 16-Oct-97 ---------------------- 1. Added a simple "pgrep" utility to the distribution. 2. Fixed an incompatibility with Perl: "{" is now treated as a normal character unless it appears in one of the precise forms "{ddd}", "{ddd,}", or "{ddd,ddd}" where "ddd" means "one or more decimal digits". 3. Fixed serious bug. If a pattern had a back reference, but the call to pcre_exec() didn't supply a large enough ovector to record the related identifying subpattern, the match always failed. PCRE now remembers the number of the largest back reference, and gets some temporary memory in which to save the offsets during matching if necessary, in order to ensure that backreferences always work. 4. Increased the compatibility with Perl in a number of ways: (a) . no longer matches \n by default; an option PCRE_DOTALL is provided to request this handling. The option can be set at compile or exec time. (b) $ matches before a terminating newline by default; an option PCRE_DOLLAR_ENDONLY is provided to override this (but not in multiline mode). The option can be set at compile or exec time. (c) The handling of \ followed by a digit other than 0 is now supposed to be the same as Perl's. If the decimal number it represents is less than 10 or there aren't that many previous left capturing parentheses, an octal escape is read. Inside a character class, it's always an octal escape, even if it is a single digit. (d) An escaped but undefined alphabetic character is taken as a literal, unless PCRE_EXTRA is set. Currently this just reserves the remaining escapes. (e) {0} is now permitted. (The previous item is removed from the compiled pattern). 5. Changed all the names of code files so that the basic parts are no longer than 10 characters, and abolished the teeny "globals.c" file. 6. Changed the handling of character classes; they are now done with a 32-byte bit map always. 7. Added the -d and /D options to pcretest to make it possible to look at the internals of compilation without having to recompile pcre. Version 0.95 23-Sep-97 ---------------------- 1. Fixed bug in pre-pass concerning escaped "normal" characters such as \x5c or \x20 at the start of a run of normal characters. These were being treated as real characters, instead of the source characters being re-checked. Version 0.94 18-Sep-97 ---------------------- 1. The functions are now thread-safe, with the caveat that the global variables containing pointers to malloc() and free() or alternative functions are the same for all threads. 2. Get pcre_study() to generate a bitmap of initial characters for non- anchored patterns when this is possible, and use it if passed to pcre_exec(). Version 0.93 15-Sep-97 ---------------------- 1. /(b)|(:+)/ was computing an incorrect first character. 2. Add pcre_study() to the API and the passing of pcre_extra to pcre_exec(), but not actually doing anything yet. 3. Treat "-" characters in classes that cannot be part of ranges as literals, as Perl does (e.g. [-az] or [az-]). 4. Set the anchored flag if a branch starts with .* or .*? because that tests all possible positions. 5. Split up into different modules to avoid including unneeded functions in a compiled binary. However, compile and exec are still in one module. The "study" function is split off. 6. The character tables are now in a separate module whose source is generated by an auxiliary program - but can then be edited by hand if required. There are now no calls to isalnum(), isspace(), isdigit(), isxdigit(), tolower() or toupper() in the code. 7. Turn the malloc/free funtions variables into pcre_malloc and pcre_free and make them global. Abolish the function for setting them, as the caller can now set them directly. Version 0.92 11-Sep-97 ---------------------- 1. A repeat with a fixed maximum and a minimum of 1 for an ordinary character (e.g. /a{1,3}/) was broken (I mis-optimized it). 2. Caseless matching was not working in character classes if the characters in the pattern were in upper case. 3. Make ranges like [W-c] work in the same way as Perl for caseless matching. 4. Make PCRE_ANCHORED public and accept as a compile option. 5. Add an options word to pcre_exec() and accept PCRE_ANCHORED and PCRE_CASELESS at run time. Add escapes \A and \I to pcretest to cause it to pass them. 6. Give an error if bad option bits passed at compile or run time. 7. Add PCRE_MULTILINE at compile and exec time, and (?m) as well. Add \M to pcretest to cause it to pass that flag. 8. Add pcre_info(), to get the number of identifying subpatterns, the stored options, and the first character, if set. 9. Recognize C+ or C{n,m} where n >= 1 as providing a fixed starting character. Version 0.91 10-Sep-97 ---------------------- 1. PCRE was failing to diagnose unlimited repeats of subpatterns that could match the empty string as in /(a*)*/. It was looping and ultimately crashing. 2. PCRE was looping on encountering an indefinitely repeated back reference to a subpattern that had matched an empty string, e.g. /(a|)\1*/. It now does what Perl does - treats the match as successful. **** pcre-8.31/132html0000755000222100022210000001546111262346436010441 00000000000000#! /usr/bin/perl -w # Script to turn PCRE man pages into HTML # Subroutine to handle font changes and other escapes sub do_line { my($s) = $_[0]; $s =~ s/ $s =~ s/>/>/g; $s =~ s"\\fI(.*?)\\f[RP]"$1"g; $s =~ s"\\fB(.*?)\\f[RP]"$1"g; $s =~ s"\\e"\\"g; $s =~ s/(?<=Copyright )\(c\)/©/g; $s; } # Subroutine to ensure not in a paragraph sub end_para { if ($inpara) { print TEMP "

qrs)123 2: 123 /\( ( ( (?>[^()]+) | ((?R)) )* ) \) /Ix Capturing subpattern count = 3 Options: extended First char = '(' Need char = ')' (ab(cd)ef) 0: (ab(cd)ef) 1: ab(cd)ef 2: ef 3: (cd) (ab(cd(ef)gh)ij) 0: (ab(cd(ef)gh)ij) 1: ab(cd(ef)gh)ij 2: ij 3: (cd(ef)gh) /^[[:alnum:]]/DZ ------------------------------------------------------------------ Bra ^ [0-9A-Za-z] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^alnum:]]/DZ ------------------------------------------------------------------ Bra ^ [\x00-/:-@[-`{-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:alpha:]]/DZ ------------------------------------------------------------------ Bra ^ [A-Za-z] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^alpha:]]/DZ ------------------------------------------------------------------ Bra ^ [\x00-@[-`{-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /[_[:alpha:]]/IS Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z /^[[:ascii:]]/DZ ------------------------------------------------------------------ Bra ^ [\x00-\x7f] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^ascii:]]/DZ ------------------------------------------------------------------ Bra ^ [\x80-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:blank:]]/DZ ------------------------------------------------------------------ Bra ^ [\x09 ] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^blank:]]/DZ ------------------------------------------------------------------ Bra ^ [\x00-\x08\x0a-\x1f!-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /[\n\x0b\x0c\x0d[:blank:]]/IS Capturing subpattern count = 0 Contains explicit CR or LF match No options No first char No need char Subject length lower bound = 1 Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 /^[[:cntrl:]]/DZ ------------------------------------------------------------------ Bra ^ [\x00-\x1f\x7f] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:digit:]]/DZ ------------------------------------------------------------------ Bra ^ [0-9] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:graph:]]/DZ ------------------------------------------------------------------ Bra ^ [!-~] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:lower:]]/DZ ------------------------------------------------------------------ Bra ^ [a-z] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:print:]]/DZ ------------------------------------------------------------------ Bra ^ [ -~] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:punct:]]/DZ ------------------------------------------------------------------ Bra ^ [!-/:-@[-`{-~] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:space:]]/DZ ------------------------------------------------------------------ Bra ^ [\x09-\x0d ] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:upper:]]/DZ ------------------------------------------------------------------ Bra ^ [A-Z] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:xdigit:]]/DZ ------------------------------------------------------------------ Bra ^ [0-9A-Fa-f] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:word:]]/DZ ------------------------------------------------------------------ Bra ^ [0-9A-Z_a-z] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^cntrl:]]/DZ ------------------------------------------------------------------ Bra ^ [ -~\x80-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[12[:^digit:]]/DZ ------------------------------------------------------------------ Bra ^ [\x00-/12:-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^blank:]]/DZ ------------------------------------------------------------------ Bra ^ [\x00-\x08\x0a-\x1f!-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /[01[:alpha:]%]/DZ ------------------------------------------------------------------ Bra [%01A-Za-z] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[[.ch.]]/I Failed: POSIX collating elements are not supported at offset 1 /[[=ch=]]/I Failed: POSIX collating elements are not supported at offset 1 /[[:rhubarb:]]/I Failed: unknown POSIX class name at offset 3 /[[:upper:]]/Ii Capturing subpattern count = 0 Options: caseless No first char No need char A 0: A a 0: a /[[:lower:]]/Ii Capturing subpattern count = 0 Options: caseless No first char No need char A 0: A a 0: a /((?-i)[[:lower:]])[[:lower:]]/Ii Capturing subpattern count = 1 Options: caseless No first char No need char ab 0: ab 1: a aB 0: aB 1: a *** Failers 0: ai 1: a Ab No match AB No match /[\200-\110]/I Failed: range out of order in character class at offset 9 /^(?(0)f|b)oo/I Failed: invalid condition (?(0) at offset 6 /This one's here because of the large output vector needed/I Capturing subpattern count = 0 No options First char = 'T' Need char = 'd' /(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/I Capturing subpattern count = 271 Max back reference = 270 No options No first char No need char \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC 0: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC 1: 1 2: 2 3: 3 4: 4 5: 5 6: 6 7: 7 8: 8 9: 9 10: 10 11: 11 12: 12 13: 13 14: 14 15: 15 16: 16 17: 17 18: 18 19: 19 20: 20 21: 21 22: 22 23: 23 24: 24 25: 25 26: 26 27: 27 28: 28 29: 29 30: 30 31: 31 32: 32 33: 33 34: 34 35: 35 36: 36 37: 37 38: 38 39: 39 40: 40 41: 41 42: 42 43: 43 44: 44 45: 45 46: 46 47: 47 48: 48 49: 49 50: 50 51: 51 52: 52 53: 53 54: 54 55: 55 56: 56 57: 57 58: 58 59: 59 60: 60 61: 61 62: 62 63: 63 64: 64 65: 65 66: 66 67: 67 68: 68 69: 69 70: 70 71: 71 72: 72 73: 73 74: 74 75: 75 76: 76 77: 77 78: 78 79: 79 80: 80 81: 81 82: 82 83: 83 84: 84 85: 85 86: 86 87: 87 88: 88 89: 89 90: 90 91: 91 92: 92 93: 93 94: 94 95: 95 96: 96 97: 97 98: 98 99: 99 100: 100 101: 101 102: 102 103: 103 104: 104 105: 105 106: 106 107: 107 108: 108 109: 109 110: 110 111: 111 112: 112 113: 113 114: 114 115: 115 116: 116 117: 117 118: 118 119: 119 120: 120 121: 121 122: 122 123: 123 124: 124 125: 125 126: 126 127: 127 128: 128 129: 129 130: 130 131: 131 132: 132 133: 133 134: 134 135: 135 136: 136 137: 137 138: 138 139: 139 140: 140 141: 141 142: 142 143: 143 144: 144 145: 145 146: 146 147: 147 148: 148 149: 149 150: 150 151: 151 152: 152 153: 153 154: 154 155: 155 156: 156 157: 157 158: 158 159: 159 160: 160 161: 161 162: 162 163: 163 164: 164 165: 165 166: 166 167: 167 168: 168 169: 169 170: 170 171: 171 172: 172 173: 173 174: 174 175: 175 176: 176 177: 177 178: 178 179: 179 180: 180 181: 181 182: 182 183: 183 184: 184 185: 185 186: 186 187: 187 188: 188 189: 189 190: 190 191: 191 192: 192 193: 193 194: 194 195: 195 196: 196 197: 197 198: 198 199: 199 200: 200 201: 201 202: 202 203: 203 204: 204 205: 205 206: 206 207: 207 208: 208 209: 209 210: 210 211: 211 212: 212 213: 213 214: 214 215: 215 216: 216 217: 217 218: 218 219: 219 220: 220 221: 221 222: 222 223: 223 224: 224 225: 225 226: 226 227: 227 228: 228 229: 229 230: 230 231: 231 232: 232 233: 233 234: 234 235: 235 236: 236 237: 237 238: 238 239: 239 240: 240 241: 241 242: 242 243: 243 244: 244 245: 245 246: 246 247: 247 248: 248 249: 249 250: 250 251: 251 252: 252 253: 253 254: 254 255: 255 256: 256 257: 257 258: 258 259: 259 260: 260 261: 261 262: 262 263: 263 264: 264 265: 265 266: 266 267: 267 268: 268 269: 269 270: ABC 271: ABC /This one's here because Perl does this differently and PCRE can't at present/I Capturing subpattern count = 0 No options First char = 'T' Need char = 't' /(main(O)?)+/I Capturing subpattern count = 2 No options First char = 'm' Need char = 'n' mainmain 0: mainmain 1: main mainOmain 0: mainOmain 1: main 2: O /These are all cases where Perl does it differently (nested captures)/I Capturing subpattern count = 1 No options First char = 'T' Need char = 's' /^(a(b)?)+$/I Capturing subpattern count = 2 Options: anchored No first char No need char aba 0: aba 1: a 2: b /^(aa(bb)?)+$/I Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb /^(aa|aa(bb))+$/I Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb /^(aa(bb)??)+$/I Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb /^(?:aa(bb)?)+$/I Capturing subpattern count = 1 Options: anchored No first char No need char aabbaa 0: aabbaa 1: bb /^(aa(b(b))?)+$/I Capturing subpattern count = 3 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb 3: b /^(?:aa(b(b))?)+$/I Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: bb 2: b /^(?:aa(b(?:b))?)+$/I Capturing subpattern count = 1 Options: anchored No first char No need char aabbaa 0: aabbaa 1: bb /^(?:aa(bb(?:b))?)+$/I Capturing subpattern count = 1 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: bbb /^(?:aa(b(?:bb))?)+$/I Capturing subpattern count = 1 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: bbb /^(?:aa(?:b(b))?)+$/I Capturing subpattern count = 1 Options: anchored No first char No need char aabbaa 0: aabbaa 1: b /^(?:aa(?:b(bb))?)+$/I Capturing subpattern count = 1 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: bb /^(aa(b(bb))?)+$/I Capturing subpattern count = 3 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: aa 2: bbb 3: bb /^(aa(bb(bb))?)+$/I Capturing subpattern count = 3 Options: anchored No first char No need char aabbbbaa 0: aabbbbaa 1: aa 2: bbbb 3: bb /--------------------------------------------------------------------/I Capturing subpattern count = 0 No options First char = '-' Need char = '-' /#/IxDZ ------------------------------------------------------------------ Bra Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: extended No first char No need char /a#/IxDZ ------------------------------------------------------------------ Bra a Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: extended First char = 'a' No need char /[\s]/DZ ------------------------------------------------------------------ Bra [\x09\x0a\x0c\x0d ] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[\S]/DZ ------------------------------------------------------------------ Bra [\x00-\x08\x0b\x0e-\x1f!-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /a(?i)b/DZ ------------------------------------------------------------------ Bra a /i b Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' (caseless) ab 0: ab aB 0: aB *** Failers No match AB No match /(a(?i)b)/DZ ------------------------------------------------------------------ Bra CBra 1 a /i b Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' (caseless) ab 0: ab 1: ab aB 0: aB 1: aB *** Failers No match AB No match / (?i)abc/IxDZ ------------------------------------------------------------------ Bra /i abc Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless extended First char = 'a' (caseless) Need char = 'c' (caseless) /#this is a comment (?i)abc/IxDZ ------------------------------------------------------------------ Bra /i abc Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless extended First char = 'a' (caseless) Need char = 'c' (caseless) /123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ ------------------------------------------------------------------ Bra 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '1' Need char = '0' /\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ ------------------------------------------------------------------ Bra 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '1' Need char = '0' /\Q\E/DZ ------------------------------------------------------------------ Bra Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char \ 0: /\Q\Ex/DZ ------------------------------------------------------------------ Bra x Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'x' No need char / \Q\E/DZ ------------------------------------------------------------------ Bra Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = ' ' No need char /a\Q\E/DZ ------------------------------------------------------------------ Bra a Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' No need char abc 0: a bca 0: a bac 0: a /a\Q\Eb/DZ ------------------------------------------------------------------ Bra ab Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' abc 0: ab /\Q\Eabc/DZ ------------------------------------------------------------------ Bra abc Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /x*+\w/DZ ------------------------------------------------------------------ Bra x*+ \w Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char *** Failers 0: F xxxxx No match /x?+/DZ ------------------------------------------------------------------ Bra x?+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /x++/DZ ------------------------------------------------------------------ Bra x++ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'x' No need char /x{1,3}+/DZ ------------------------------------------------------------------ Bra Once x x{0,2} Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'x' No need char /(x)*+/DZ ------------------------------------------------------------------ Bra Braposzero CBraPos 1 x KetRpos Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 No options No first char No need char /^(\w++|\s++)*$/I Capturing subpattern count = 1 Options: anchored No first char No need char now is the time for all good men to come to the aid of the party 0: now is the time for all good men to come to the aid of the party 1: party *** Failers No match this is not a line with only words and spaces! No match /(\d++)(\w)/I Capturing subpattern count = 2 No options No first char No need char 12345a 0: 12345a 1: 12345 2: a *** Failers No match 12345+ No match /a++b/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' aaab 0: aaab /(a++b)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' aaab 0: aaab 1: aaab /(a++)b/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' aaab 0: aaab 1: aaa /([^()]++|\([^()]*\))+/I Capturing subpattern count = 1 No options No first char No need char ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: x /\(([^()]++|\([^()]+\))+\)/I Capturing subpattern count = 1 No options First char = '(' Need char = ')' (abc) 0: (abc) 1: abc (abc(def)xyz) 0: (abc(def)xyz) 1: xyz *** Failers No match ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /(abc){1,3}+/DZ ------------------------------------------------------------------ Bra Once CBra 1 abc Ket Brazero Bra CBra 1 abc Ket Brazero CBra 1 abc Ket Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 No options First char = 'a' Need char = 'c' /a+?+/I Failed: nothing to repeat at offset 3 /a{2,3}?+b/I Failed: nothing to repeat at offset 7 /(?U)a+?+/I Failed: nothing to repeat at offset 7 /a{2,3}?+b/IU Failed: nothing to repeat at offset 7 /x(?U)a++b/DZ ------------------------------------------------------------------ Bra x a++ b Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'x' Need char = 'b' xaaaab 0: xaaaab /(?U)xa++b/DZ ------------------------------------------------------------------ Bra x a++ b Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: ungreedy First char = 'x' Need char = 'b' xaaaab 0: xaaaab /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/DZ ------------------------------------------------------------------ Bra ^ CBra 1 CBra 2 a+ Ket CBra 3 [ab]+? Ket CBra 4 [bc]+ Ket CBra 5 \w* Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 5 Options: anchored No first char No need char /^x(?U)a+b/DZ ------------------------------------------------------------------ Bra ^ x a++ b Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char Need char = 'b' /^x(?U)(a+)b/DZ ------------------------------------------------------------------ Bra ^ x CBra 1 a+? Ket b Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: anchored No first char Need char = 'b' /[.x.]/I Failed: POSIX collating elements are not supported at offset 0 /[=x=]/I Failed: POSIX collating elements are not supported at offset 0 /[:x:]/I Failed: POSIX named classes are supported only within a class at offset 0 /\l/I Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 /\L/I Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 /\N{name}/I Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 /\u/I Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 /\U/I Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 /[/I Failed: missing terminating ] for character class at offset 1 /[a-/I Failed: missing terminating ] for character class at offset 3 /[[:space:]/I Failed: missing terminating ] for character class at offset 10 /[\s]/IDZ ------------------------------------------------------------------ Bra [\x09\x0a\x0c\x0d ] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[[:space:]]/IDZ ------------------------------------------------------------------ Bra [\x09-\x0d ] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[[:space:]abcde]/IDZ ------------------------------------------------------------------ Bra [\x09-\x0d a-e] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/Ix Capturing subpattern count = 0 Options: extended First char = '<' Need char = '>' <> 0: <> 0: hij> 0: hij> hij> 0: def> 0: def> 0: <> *** Failers No match iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|IDZ ------------------------------------------------------------------ Bra 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X \b Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '8' Need char = 'X' Max lookbehind = 1 |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|IDZ ------------------------------------------------------------------ Bra $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X \b Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '$' Need char = 'X' Max lookbehind = 1 /(.*)\d+\1/I Capturing subpattern count = 1 Max back reference = 1 No options No first char No need char /(.*)\d+/I Capturing subpattern count = 1 No options First char at start or follows newline No need char /(.*)\d+\1/Is Capturing subpattern count = 1 Max back reference = 1 Options: dotall No first char No need char /(.*)\d+/Is Capturing subpattern count = 1 Options: anchored dotall No first char No need char /(.*(xyz))\d+\2/I Capturing subpattern count = 2 Max back reference = 2 No options First char at start or follows newline Need char = 'z' /((.*))\d+\1/I Capturing subpattern count = 2 Max back reference = 1 No options No first char No need char abc123bc 0: bc123bc 1: bc 2: bc /a[b]/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /(?=a).*/I Capturing subpattern count = 0 No options First char = 'a' No need char /(?=abc).xyz/IiI Capturing subpattern count = 0 Options: caseless First char = 'a' (caseless) Need char = 'z' (caseless) /(?=abc)(?i).xyz/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'z' (caseless) /(?=a)(?=b)/I Capturing subpattern count = 0 No options First char = 'a' No need char /(?=.)a/I Capturing subpattern count = 0 No options First char = 'a' No need char /((?=abcda)a)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'a' /((?=abcda)ab)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' /()a/I Capturing subpattern count = 1 No options No first char Need char = 'a' /(?(1)ab|ac)(.)/I Capturing subpattern count = 1 No options First char = 'a' No need char /(?(1)abz|acz)(.)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'z' /(?(1)abz)(.)/I Capturing subpattern count = 1 No options No first char No need char /(?(1)abz)(1)23/I Capturing subpattern count = 1 No options No first char Need char = '3' /(a)+/I Capturing subpattern count = 1 No options First char = 'a' No need char /(a){2,3}/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'a' /(a)*/I Capturing subpattern count = 1 No options No first char No need char /[a]/I Capturing subpattern count = 0 No options First char = 'a' No need char /[ab]/I Capturing subpattern count = 0 No options No first char No need char /[ab]/IS Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b /[^a]/I Capturing subpattern count = 0 No options No first char No need char /\d456/I Capturing subpattern count = 0 No options No first char Need char = '6' /\d456/IS Capturing subpattern count = 0 No options No first char Need char = '6' Subject length lower bound = 4 Starting byte set: 0 1 2 3 4 5 6 7 8 9 /a^b/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /^a/Im Capturing subpattern count = 0 Options: multiline First char at start or follows newline Need char = 'a' abcde 0: a xy\nabc 0: a *** Failers No match xyabc No match /c|abc/I Capturing subpattern count = 0 No options No first char Need char = 'c' /(?i)[ab]/IS Capturing subpattern count = 0 Options: caseless No first char No need char Subject length lower bound = 1 Starting byte set: A B a b /[ab](?i)cd/IS Capturing subpattern count = 0 No options No first char Need char = 'd' (caseless) Subject length lower bound = 3 Starting byte set: a b /abc(?C)def/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' abcdef --->abcdef 0 ^ ^ d 0: abcdef 1234abcdef --->1234abcdef 0 ^ ^ d 0: abcdef *** Failers No match abcxyz No match abcxyzf --->abcxyzf 0 ^ ^ d No match /abc(?C)de(?C1)f/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' 123abcdef --->123abcdef 0 ^ ^ d 1 ^ ^ f 0: abcdef /(?C1)\dabc(?C2)def/IS Capturing subpattern count = 0 No options No first char Need char = 'f' Subject length lower bound = 7 Starting byte set: 0 1 2 3 4 5 6 7 8 9 1234abcdef --->1234abcdef 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d 2 ^ ^ d 0: 4abcdef *** Failers No match abcdef No match /(?C1)\dabc(?C2)def/ISS Capturing subpattern count = 0 No options No first char Need char = 'f' 1234abcdef --->1234abcdef 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d 2 ^ ^ d 0: 4abcdef *** Failers No match abcdef --->abcdef 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d No match /(?C255)ab/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /(?C256)ab/I Failed: number after (?C is > 255 at offset 6 /(?Cab)xx/I Failed: closing ) for (?C expected at offset 3 /(?C12vr)x/I Failed: closing ) for (?C expected at offset 5 /abc(?C)def/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' *** Failers No match \x83\x0\x61bcdef --->\x83\x00abcdef 0 ^ ^ d 0: abcdef /(abc)(?C)de(?C1)f/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'f' 123abcdef --->123abcdef 0 ^ ^ d 1 ^ ^ f 0: abcdef 1: abc 123abcdef\C+ Callout 0: last capture = 1 0: 1: abc --->123abcdef ^ ^ d Callout 1: last capture = 1 0: 1: abc --->123abcdef ^ ^ f 0: abcdef 1: abc 123abcdef\C- 0: abcdef 1: abc *** Failers No match 123abcdef\C!1 --->123abcdef 0 ^ ^ d 1 ^ ^ f No match /(?C0)(abc(?C1))*/I Capturing subpattern count = 1 No options No first char No need char abcabcabc --->abcabcabc 0 ^ (abc(?C1))* 1 ^ ^ ) 1 ^ ^ ) 1 ^ ^ ) 0: abcabcabc 1: abc abcabc\C!1!3 --->abcabc 0 ^ (abc(?C1))* 1 ^ ^ ) 1 ^ ^ ) 0: abcabc 1: abc *** Failers --->*** Failers 0 ^ (abc(?C1))* 0: abcabcabc\C!1!3 --->abcabcabc 0 ^ (abc(?C1))* 1 ^ ^ ) 1 ^ ^ ) 1 ^ ^ ) 0: abcabc 1: abc /(\d{3}(?C))*/I Capturing subpattern count = 1 No options No first char No need char 123\C+ Callout 0: last capture = -1 0: --->123 ^ ^ ) 0: 123 1: 123 123456\C+ Callout 0: last capture = -1 0: --->123456 ^ ^ ) Callout 0: last capture = 1 0: 1: 123 --->123456 ^ ^ ) 0: 123456 1: 456 123456789\C+ Callout 0: last capture = -1 0: --->123456789 ^ ^ ) Callout 0: last capture = 1 0: 1: 123 --->123456789 ^ ^ ) Callout 0: last capture = 1 0: 1: 456 --->123456789 ^ ^ ) 0: 123456789 1: 789 /((xyz)(?C)p|(?C1)xyzabc)/I Capturing subpattern count = 2 No options First char = 'x' No need char xyzabc\C+ Callout 0: last capture = 2 0: 1: 2: xyz --->xyzabc ^ ^ p Callout 1: last capture = -1 0: --->xyzabc ^ x 0: xyzabc 1: xyzabc /(X)((xyz)(?C)p|(?C1)xyzabc)/I Capturing subpattern count = 3 No options First char = 'X' Need char = 'x' Xxyzabc\C+ Callout 0: last capture = 3 0: 1: X 2: 3: xyz --->Xxyzabc ^ ^ p Callout 1: last capture = 1 0: 1: X --->Xxyzabc ^^ x 0: Xxyzabc 1: X 2: xyzabc /(?=(abc))(?C)abcdef/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'f' abcdef\C+ Callout 0: last capture = 1 0: 1: abc --->abcdef ^ a 0: abcdef 1: abc /(?!(abc)(?C1)d)(?C2)abcxyz/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'z' abcxyz\C+ Callout 1: last capture = 1 0: 1: abc --->abcxyz ^ ^ d Callout 2: last capture = -1 0: --->abcxyz ^ a 0: abcxyz /(?<=(abc)(?C))xyz/I Capturing subpattern count = 1 No options First char = 'x' Need char = 'z' Max lookbehind = 3 abcxyz\C+ Callout 0: last capture = 1 0: 1: abc --->abcxyz ^ ) 0: xyz 1: abc /a(b+)(c*)(?C1)/I Capturing subpattern count = 2 No options First char = 'a' Need char = 'b' abbbbbccc\C*1 --->abbbbbccc 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 No match /a(b+?)(c*?)(?C1)/I Capturing subpattern count = 2 No options First char = 'a' Need char = 'b' abbbbbccc\C*1 --->abbbbbccc 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 1 ^ ^ Callout data = 1 No match /(?C)abc/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /(?C)^abc/I Capturing subpattern count = 0 Options: anchored No first char No need char /(?C)a|b/IS Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b /(?R)/I Failed: recursive call could loop indefinitely at offset 3 /(a|(?R))/I Failed: recursive call could loop indefinitely at offset 6 /(ab|(bc|(de|(?R))))/I Failed: recursive call could loop indefinitely at offset 15 /x(ab|(bc|(de|(?R))))/I Capturing subpattern count = 3 No options First char = 'x' No need char xab 0: xab 1: ab xbc 0: xbc 1: bc 2: bc xde 0: xde 1: de 2: de 3: de xxab 0: xxab 1: xab 2: xab 3: xab xxxab 0: xxxab 1: xxab 2: xxab 3: xxab *** Failers No match xyab No match /(ab|(bc|(de|(?1))))/I Failed: recursive call could loop indefinitely at offset 15 /x(ab|(bc|(de|(?1)x)x)x)/I Failed: recursive call could loop indefinitely at offset 16 /^([^()]|\((?1)*\))*$/I Capturing subpattern count = 1 Options: anchored No first char No need char abc 0: abc 1: c a(b)c 0: a(b)c 1: c a(b(c))d 0: a(b(c))d 1: d *** Failers) No match a(b(c)d No match /^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3)]*+) | (?2)) * >))/Ix Capturing subpattern count = 2 Options: extended First char = '<' Need char = '>' <> 0: <> 1: <> 2: <> 0: 1: 2: hij> 0: hij> 1: hij> 2: hij> hij> 0: 1: 2: def> 0: def> 1: def> 2: def> 0: <> 1: <> 2: <> *** Failers No match b|c)d(?Pe)/DZ ------------------------------------------------------------------ Bra a CBra 1 b Alt c Ket d CBra 2 e Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 Named capturing subpatterns: longername2 2 name1 1 No options First char = 'a' Need char = 'e' abde 0: abde 1: b 2: e acde 0: acde 1: c 2: e /(?:a(?Pc(?Pd)))(?Pa)/DZ ------------------------------------------------------------------ Bra Bra a CBra 1 c CBra 2 d Ket Ket Ket CBra 3 a Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 3 Named capturing subpatterns: a 3 c 1 d 2 No options First char = 'a' Need char = 'a' /(?Pa)...(?P=a)bbb(?P>a)d/DZ ------------------------------------------------------------------ Bra CBra 1 a Ket Any Any Any \1 bbb Recurse d Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Max back reference = 1 Named capturing subpatterns: a 1 No options First char = 'a' Need char = 'd' /^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/Ii Capturing subpattern count = 4 Max back reference = 4 Named capturing subpatterns: four 4 one 1 three 3 two 2 Options: anchored caseless No first char No need char 1221 0: 1221 1: 1221 2: 1 Satan, oscillate my metallic sonatas! 0: Satan, oscillate my metallic sonatas! 1: 2: 3: Satan, oscillate my metallic sonatas 4: S A man, a plan, a canal: Panama! 0: A man, a plan, a canal: Panama! 1: 2: 3: A man, a plan, a canal: Panama 4: A Able was I ere I saw Elba. 0: Able was I ere I saw Elba. 1: 2: 3: Able was I ere I saw Elba 4: A *** Failers No match The quick brown fox No match /((?(R)a|b))\1(?1)?/I Capturing subpattern count = 1 Max back reference = 1 No options No first char No need char bb 0: bb 1: b bbaa 0: bba 1: b /(.*)a/Is Capturing subpattern count = 1 Options: anchored dotall No first char Need char = 'a' /(.*)a\1/Is Capturing subpattern count = 1 Max back reference = 1 Options: dotall No first char Need char = 'a' /(.*)a(b)\2/Is Capturing subpattern count = 2 Max back reference = 2 Options: anchored dotall No first char Need char = 'b' /((.*)a|(.*)b)z/Is Capturing subpattern count = 3 Options: anchored dotall No first char Need char = 'z' /((.*)a|(.*)b)z\1/Is Capturing subpattern count = 3 Max back reference = 1 Options: dotall No first char Need char = 'z' /((.*)a|(.*)b)z\2/Is Capturing subpattern count = 3 Max back reference = 2 Options: dotall No first char Need char = 'z' /((.*)a|(.*)b)z\3/Is Capturing subpattern count = 3 Max back reference = 3 Options: dotall No first char Need char = 'z' /((.*)a|^(.*)b)z\3/Is Capturing subpattern count = 3 Max back reference = 3 Options: anchored dotall No first char Need char = 'z' /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/Is Capturing subpattern count = 31 Options: anchored dotall No first char No need char /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/Is Capturing subpattern count = 31 Max back reference = 31 Options: dotall No first char No need char /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/Is Capturing subpattern count = 32 Max back reference = 32 Options: dotall No first char No need char /(a)(bc)/INDZ ------------------------------------------------------------------ Bra Bra a Ket Bra bc Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: no_auto_capture First char = 'a' Need char = 'c' abc 0: abc /(?Pa)(bc)/INDZ ------------------------------------------------------------------ Bra CBra 1 a Ket Bra bc Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Named capturing subpatterns: one 1 Options: no_auto_capture First char = 'a' Need char = 'c' abc 0: abc 1: a /(a)(?Pbc)/INDZ ------------------------------------------------------------------ Bra Bra a Ket CBra 1 bc Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Named capturing subpatterns: named 1 Options: no_auto_capture First char = 'a' Need char = 'c' /(a+)*zz/I Capturing subpattern count = 1 No options No first char Need char = 'z' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M Minimum match() limit = 8 Minimum match() recursion limit = 6 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaz\M Minimum match() limit = 32768 Minimum match() recursion limit = 42 No match /(aaa(?C1)bbb|ab)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' aaabbb --->aaabbb 1 ^ ^ b 0: aaabbb 1: aaabbb aaabbb\C*0 --->aaabbb 1 ^ ^ b 0: aaabbb 1: aaabbb aaabbb\C*1 --->aaabbb 1 ^ ^ b Callout data = 1 0: ab 1: ab aaabbb\C*-1 --->aaabbb 1 ^ ^ b Callout data = -1 No match /ab(?Pcd)ef(?Pgh)/I Capturing subpattern count = 2 Named capturing subpatterns: one 1 two 2 No options First char = 'a' Need char = 'h' abcdefgh 0: abcdefgh 1: cd 2: gh abcdefgh\C1\Gtwo 0: abcdefgh 1: cd 2: gh 1C cd (2) G gh (2) two abcdefgh\Cone\Ctwo 0: abcdefgh 1: cd 2: gh 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)(?P)/DZ ------------------------------------------------------------------ Bra CBra 1 Ket CBra 2 Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 Named capturing subpatterns: Tes 1 Test 2 No options No first char No need char /(?P)(?P)/DZ ------------------------------------------------------------------ Bra CBra 1 Ket CBra 2 Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 Named capturing subpatterns: Tes 2 Test 1 No options No first char No need char /(?Pzz)(?Paa)/I Capturing subpattern count = 2 Named capturing subpatterns: A 2 Z 1 No options First char = 'z' Need char = 'a' zzaa\CZ 0: zzaa 1: zz 2: aa C zz (2) Z zzaa\CA 0: zzaa 1: zz 2: aa C aa (2) A /(?Peks)(?Peccs)/I Failed: two named subpatterns have the same name at offset 15 /(?Pabc(?Pdef)(?Pxyz))/I Failed: two named subpatterns have the same name at offset 30 "\[((?P\d+)(,(?P>elem))*)\]"I Capturing subpattern count = 3 Named capturing subpatterns: elem 2 No options First char = '[' Need char = ']' [10,20,30,5,5,4,4,2,43,23,4234] 0: [10,20,30,5,5,4,4,2,43,23,4234] 1: 10,20,30,5,5,4,4,2,43,23,4234 2: 10 3: ,4234 *** Failers No match [] No match "\[((?P\d+)(,(?P>elem))*)?\]"I Capturing subpattern count = 3 Named capturing subpatterns: elem 2 No options First char = '[' Need char = ']' [10,20,30,5,5,4,4,2,43,23,4234] 0: [10,20,30,5,5,4,4,2,43,23,4234] 1: 10,20,30,5,5,4,4,2,43,23,4234 2: 10 3: ,4234 [] 0: [] /(a(b(?2)c))?/DZ ------------------------------------------------------------------ Bra Brazero CBra 1 a CBra 2 b Recurse c Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 No options No first char No need char /(a(b(?2)c))*/DZ ------------------------------------------------------------------ Bra Brazero CBra 1 a CBra 2 b Recurse c Ket KetRmax Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 No options No first char No need char /(a(b(?2)c)){0,2}/DZ ------------------------------------------------------------------ Bra Brazero Bra CBra 1 a CBra 2 b Recurse c Ket Ket Brazero CBra 1 a CBra 2 b Recurse c Ket Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 No options No first char No need char /[ab]{1}+/DZ ------------------------------------------------------------------ Bra Once [ab]{1,1} Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/Ii Capturing subpattern count = 3 Options: caseless No first char Need char = 'g' (caseless) Baby Bjorn Active Carrier - With free SHIPPING!! 0: Baby Bjorn Active Carrier - With free SHIPPING!! 1: Baby Bjorn Active Carrier - With free SHIPPING!! /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/IiS Capturing subpattern count = 3 Options: caseless No first char Need char = 'g' (caseless) Subject length lower bound = 8 No set of starting bytes Baby Bjorn Active Carrier - With free SHIPPING!! 0: Baby Bjorn Active Carrier - With free SHIPPING!! 1: Baby Bjorn Active Carrier - With free SHIPPING!! /a*.*b/ISDZ ------------------------------------------------------------------ Bra a* Any* b Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char Need char = 'b' Subject length lower bound = 1 No set of starting bytes /(a|b)*.?c/ISDZ ------------------------------------------------------------------ Bra Brazero CBra 1 a Alt b KetRmax Any? c Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 No options No first char Need char = 'c' Subject length lower bound = 1 No set of starting bytes /abc(?C255)de(?C)f/DZ ------------------------------------------------------------------ Bra abc Callout 255 10 1 de Callout 0 16 1 f Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' /abcde/ICDZ ------------------------------------------------------------------ Bra Callout 255 0 1 a Callout 255 1 1 b Callout 255 2 1 c Callout 255 3 1 d Callout 255 4 1 e Callout 255 5 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: First char = 'a' Need char = 'e' abcde --->abcde +0 ^ a +1 ^^ b +2 ^ ^ c +3 ^ ^ d +4 ^ ^ e +5 ^ ^ 0: abcde abcdfe --->abcdfe +0 ^ a +1 ^^ b +2 ^ ^ c +3 ^ ^ d +4 ^ ^ e No match /a*b/ICDZS ------------------------------------------------------------------ Bra Callout 255 0 2 a*+ Callout 255 2 1 b Callout 255 3 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: No first char Need char = 'b' Subject length lower bound = 1 Starting byte set: a b ab --->ab +0 ^ a* +2 ^^ b +3 ^ ^ 0: ab aaaab --->aaaab +0 ^ a* +2 ^ ^ b +3 ^ ^ 0: aaaab aaaacb --->aaaacb +0 ^ a* +2 ^ ^ b +0 ^ a* +2 ^ ^ b +0 ^ a* +2 ^ ^ b +0 ^ a* +2 ^^ b +0 ^ a* +2 ^ b +3 ^^ 0: b /a*b/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 2 a*+ Callout 255 2 1 b Callout 255 3 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: No first char Need char = 'b' ab --->ab +0 ^ a* +2 ^^ b +3 ^ ^ 0: ab aaaab --->aaaab +0 ^ a* +2 ^ ^ b +3 ^ ^ 0: aaaab aaaacb --->aaaacb +0 ^ a* +2 ^ ^ b +0 ^ a* +2 ^ ^ b +0 ^ a* +2 ^ ^ b +0 ^ a* +2 ^^ b +0 ^ a* +2 ^ b +0 ^ a* +2 ^ b +3 ^^ 0: b /a+b/ICDZ ------------------------------------------------------------------ Bra Callout 255 0 2 a++ Callout 255 2 1 b Callout 255 3 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: First char = 'a' Need char = 'b' ab --->ab +0 ^ a+ +2 ^^ b +3 ^ ^ 0: ab aaaab --->aaaab +0 ^ a+ +2 ^ ^ b +3 ^ ^ 0: aaaab aaaacb --->aaaacb +0 ^ a+ +2 ^ ^ b +0 ^ a+ +2 ^ ^ b +0 ^ a+ +2 ^ ^ b +0 ^ a+ +2 ^^ b No match /(abc|def)x/ICDZS ------------------------------------------------------------------ Bra Callout 255 0 9 CBra 1 Callout 255 1 1 a Callout 255 2 1 b Callout 255 3 1 c Callout 255 4 0 Alt Callout 255 5 1 d Callout 255 6 1 e Callout 255 7 1 f Callout 255 8 0 Ket Callout 255 9 1 x Callout 255 10 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: No first char Need char = 'x' Subject length lower bound = 4 Starting byte set: a d abcx --->abcx +0 ^ (abc|def) +1 ^ a +2 ^^ b +3 ^ ^ c +4 ^ ^ | +9 ^ ^ x +10 ^ ^ 0: abcx 1: abc defx --->defx +0 ^ (abc|def) +1 ^ a +5 ^ d +6 ^^ e +7 ^ ^ f +8 ^ ^ ) +9 ^ ^ x +10 ^ ^ 0: defx 1: def ** Failers No match abcdefzx --->abcdefzx +0 ^ (abc|def) +1 ^ a +2 ^^ b +3 ^ ^ c +4 ^ ^ | +9 ^ ^ x +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +6 ^^ e +7 ^ ^ f +8 ^ ^ ) +9 ^ ^ x No match /(abc|def)x/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 9 CBra 1 Callout 255 1 1 a Callout 255 2 1 b Callout 255 3 1 c Callout 255 4 0 Alt Callout 255 5 1 d Callout 255 6 1 e Callout 255 7 1 f Callout 255 8 0 Ket Callout 255 9 1 x Callout 255 10 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: No first char Need char = 'x' abcx --->abcx +0 ^ (abc|def) +1 ^ a +2 ^^ b +3 ^ ^ c +4 ^ ^ | +9 ^ ^ x +10 ^ ^ 0: abcx 1: abc defx --->defx +0 ^ (abc|def) +1 ^ a +5 ^ d +6 ^^ e +7 ^ ^ f +8 ^ ^ ) +9 ^ ^ x +10 ^ ^ 0: defx 1: def ** Failers No match abcdefzx --->abcdefzx +0 ^ (abc|def) +1 ^ a +2 ^^ b +3 ^ ^ c +4 ^ ^ | +9 ^ ^ x +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +6 ^^ e +7 ^ ^ f +8 ^ ^ ) +9 ^ ^ x +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d No match /(ab|cd){3,4}/IC Capturing subpattern count = 1 Options: No first char No need char ababab --->ababab +0 ^ (ab|cd){3,4} +1 ^ a +2 ^^ b +3 ^ ^ | +1 ^ ^ a +2 ^ ^ b +3 ^ ^ | +1 ^ ^ a +2 ^ ^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +12 ^ ^ 0: ababab 1: ab abcdabcd --->abcdabcd +0 ^ (ab|cd){3,4} +1 ^ a +2 ^^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +2 ^ ^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +12 ^ ^ 0: abcdabcd 1: cd abcdcdcdcdcd --->abcdcdcdcdcd +0 ^ (ab|cd){3,4} +1 ^ a +2 ^^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +12 ^ ^ 0: abcdcdcd 1: cd /([ab]{,4}c|xy)/ICDZS ------------------------------------------------------------------ Bra Callout 255 0 14 CBra 1 Callout 255 1 4 [ab] Callout 255 5 1 { Callout 255 6 1 , Callout 255 7 1 4 Callout 255 8 1 } Callout 255 9 1 c Callout 255 10 0 Alt Callout 255 11 1 x Callout 255 12 1 y Callout 255 13 0 Ket Callout 255 14 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: No first char No need char Subject length lower bound = 2 Starting byte set: a b x Note: that { does NOT introduce a quantifier --->Note: that { does NOT introduce a quantifier +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x No match /([ab]{,4}c|xy)/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 14 CBra 1 Callout 255 1 4 [ab] Callout 255 5 1 { Callout 255 6 1 , Callout 255 7 1 4 Callout 255 8 1 } Callout 255 9 1 c Callout 255 10 0 Alt Callout 255 11 1 x Callout 255 12 1 y Callout 255 13 0 Ket Callout 255 14 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: No first char No need char Note: that { does NOT introduce a quantifier --->Note: that { does NOT introduce a quantifier +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x No match /([ab]{1,4}c|xy){4,5}?123/ICDZ ------------------------------------------------------------------ Bra Callout 255 0 21 CBra 1 Callout 255 1 9 [ab]{1,4} Callout 255 10 1 c Callout 255 11 0 Alt Callout 255 12 1 x Callout 255 13 1 y Callout 255 14 0 Ket CBra 1 Callout 255 1 9 [ab]{1,4} Callout 255 10 1 c Callout 255 11 0 Alt Callout 255 12 1 x Callout 255 13 1 y Callout 255 14 0 Ket CBra 1 Callout 255 1 9 [ab]{1,4} Callout 255 10 1 c Callout 255 11 0 Alt Callout 255 12 1 x Callout 255 13 1 y Callout 255 14 0 Ket CBra 1 Callout 255 1 9 [ab]{1,4} Callout 255 10 1 c Callout 255 11 0 Alt Callout 255 12 1 x Callout 255 13 1 y Callout 255 14 0 Ket Braminzero CBra 1 Callout 255 1 9 [ab]{1,4} Callout 255 10 1 c Callout 255 11 0 Alt Callout 255 12 1 x Callout 255 13 1 y Callout 255 14 0 Ket Callout 255 21 1 1 Callout 255 22 1 2 Callout 255 23 1 3 Callout 255 24 0 Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: No first char Need char = '3' aacaacaacaacaac123 --->aacaacaacaacaac123 +0 ^ ([ab]{1,4}c|xy){4,5}? +1 ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +21 ^ ^ 1 +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +21 ^ ^ 1 +22 ^ ^ 2 +23 ^ ^ 3 +24 ^ ^ 0: aacaacaacaacaac123 1: aac /\b.*/I Capturing subpattern count = 0 No options No first char No need char Max lookbehind = 1 ab cd\>1 0: cd /\b.*/Is Capturing subpattern count = 0 Options: dotall No first char No need char Max lookbehind = 1 ab cd\>1 0: cd /(?!.bcd).*/I Capturing subpattern count = 0 No options No first char No need char Xbcd12345 0: bcd12345 /abcde/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'e' ab\P Partial match: ab abc\P Partial match: abc abcd\P Partial match: abcd abcde\P 0: abcde the quick brown abc\P Partial match: abc ** Failers\P No match the quick brown abxyz fox\P No match "^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$"I Capturing subpattern count = 3 Options: anchored No first char Need char = '/' 13/05/04\P 0: 13/05/04 1: 13 2: 05 13/5/2004\P 0: 13/5/2004 1: 13 2: 5 3: 20 02/05/09\P 0: 02/05/09 1: 02 2: 05 1\P Partial match: 1 1/2\P Partial match: 1/2 1/2/0\P Partial match: 1/2/0 1/2/04\P 0: 1/2/04 1: 1 2: 2 0\P Partial match: 0 02/\P Partial match: 02/ 02/0\P Partial match: 02/0 02/1\P Partial match: 02/1 ** Failers\P No match \P No match 123\P No match 33/4/04\P No match 3/13/04\P No match 0/1/2003\P No match 0/\P No match 02/0/\P No match 02/13\P No match /0{0,2}ABC/I Capturing subpattern count = 0 No options No first char Need char = 'C' /\d{3,}ABC/I Capturing subpattern count = 0 No options No first char Need char = 'C' /\d*ABC/I Capturing subpattern count = 0 No options No first char Need char = 'C' /[abc]+DE/I Capturing subpattern count = 0 No options No first char Need char = 'E' /[abc]?123/I Capturing subpattern count = 0 No options No first char Need char = '3' 123\P 0: 123 a\P Partial match: a b\P Partial match: b c\P Partial match: c c12\P Partial match: c12 c123\P 0: c123 /^(?:\d){3,5}X/I Capturing subpattern count = 0 Options: anchored No first char Need char = 'X' 1\P Partial match: 1 123\P Partial match: 123 123X 0: 123X 1234\P Partial match: 1234 1234X 0: 1234X 12345\P Partial match: 12345 12345X 0: 12345X *** Failers No match 1X No match 123456\P No match /abc/IS>testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Subject length lower bound = 3 No set of starting bytes Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Compiled pattern written to testsavedregex testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Subject length lower bound = 3 No set of starting bytes Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Compiled pattern written to testsavedregex testsavedregex Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex Capturing subpattern count = 1 No options No first char No need char Compiled pattern written to testsavedregex testsavedregex Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex Capturing subpattern count = 1 No options No first char No need char Compiled pattern written to testsavedregex (.)*~smgI Capturing subpattern count = 3 Max back reference = 1 Options: multiline dotall First char = '<' Need char = '>' \J1024\n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n 0: \x0a\x0aPartner der LCO\x0ade\x0aPartner der LINEAS Consulting\x0aGmbH\x0aLINEAS Consulting GmbH Hamburg\x0aPartnerfirmen\x0a30 days\x0aindex,follow\x0a\x0aja\x0a3\x0aPartner\x0a\x0a\x0aLCO\x0aLINEAS Consulting\x0a15.10.2003\x0a\x0a\x0a\x0a\x0aDie Partnerfirmen der LINEAS Consulting\x0aGmbH\x0a\x0a\x0a \x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a 1: seite 2: \x0a 3: seite /^a/IF Capturing subpattern count = 0 Options: anchored No first char No need char /line\nbreak/I Capturing subpattern count = 0 Contains explicit CR or LF match No options First char = 'l' Need char = 'k' this is a line\nbreak 0: line\x0abreak line one\nthis is a line\nbreak in the second line 0: line\x0abreak /line\nbreak/If Capturing subpattern count = 0 Contains explicit CR or LF match Options: firstline First char = 'l' Need char = 'k' this is a line\nbreak 0: line\x0abreak ** Failers No match line one\nthis is a line\nbreak in the second line No match /line\nbreak/Imf Capturing subpattern count = 0 Contains explicit CR or LF match Options: multiline firstline First char = 'l' Need char = 'k' this is a line\nbreak 0: line\x0abreak ** Failers No match line one\nthis is a line\nbreak in the second line No match /(?i)(?-i)AbCd/I Capturing subpattern count = 0 No options First char = 'A' Need char = 'd' AbCd 0: AbCd ** Failers No match abcd No match /a{11111111111111111111}/I Failed: number too big in {} quantifier at offset 22 /(){64294967295}/I Failed: number too big in {} quantifier at offset 14 /(){2,4294967295}/I Failed: number too big in {} quantifier at offset 15 "(?i:a)(?i:b)(?i:c)(?i:d)(?i:e)(?i:f)(?i:g)(?i:h)(?i:i)(?i:j)(k)(?i:l)A\1B"I Capturing subpattern count = 1 Max back reference = 1 No options First char = 'a' (caseless) Need char = 'B' abcdefghijklAkB 0: abcdefghijklAkB 1: k "(?Pa)(?Pb)(?Pc)(?Pd)(?Pe)(?Pf)(?Pg)(?Ph)(?Pi)(?Pj)(?Pk)(?Pl)A\11B"I Capturing subpattern count = 12 Max back reference = 11 Named capturing subpatterns: n0 1 n1 2 n10 11 n11 12 n2 3 n3 4 n4 5 n5 6 n6 7 n7 8 n8 9 n9 10 No options First char = 'a' Need char = 'B' abcdefghijklAkB 0: abcdefghijklAkB 1: a 2: b 3: c 4: d 5: e 6: f 7: g 8: h 9: i 10: j 11: k 12: l "(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)A\11B"I Capturing subpattern count = 12 Max back reference = 11 No options First char = 'a' Need char = 'B' abcdefghijklAkB 0: abcdefghijklAkB 1: a 2: b 3: c 4: d 5: e 6: f 7: g 8: h 9: i 10: j 11: k 12: l "(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)"I Capturing subpattern count = 101 Named capturing subpatterns: name0 1 name1 2 name10 11 name100 101 name11 12 name12 13 name13 14 name14 15 name15 16 name16 17 name17 18 name18 19 name19 20 name2 3 name20 21 name21 22 name22 23 name23 24 name24 25 name25 26 name26 27 name27 28 name28 29 name29 30 name3 4 name30 31 name31 32 name32 33 name33 34 name34 35 name35 36 name36 37 name37 38 name38 39 name39 40 name4 5 name40 41 name41 42 name42 43 name43 44 name44 45 name45 46 name46 47 name47 48 name48 49 name49 50 name5 6 name50 51 name51 52 name52 53 name53 54 name54 55 name55 56 name56 57 name57 58 name58 59 name59 60 name6 7 name60 61 name61 62 name62 63 name63 64 name64 65 name65 66 name66 67 name67 68 name68 69 name69 70 name7 8 name70 71 name71 72 name72 73 name73 74 name74 75 name75 76 name76 77 name77 78 name78 79 name79 80 name8 9 name80 81 name81 82 name82 83 name83 84 name84 85 name85 86 name86 87 name87 88 name88 89 name89 90 name9 10 name90 91 name91 92 name92 93 name93 94 name94 95 name95 96 name96 97 name97 98 name98 99 name99 100 No options First char = 'a' Need char = 'a' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Matched, but too many substrings 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: a 2: a 3: a 4: a 5: a 6: a 7: a 8: a 9: a 10: a 11: a 12: a 13: a 14: a "(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)"I Capturing subpattern count = 101 No options First char = 'a' Need char = 'a' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Matched, but too many substrings 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: a 2: a 3: a 4: a 5: a 6: a 7: a 8: a 9: a 10: a 11: a 12: a 13: a 14: a /[^()]*(?:\((?R)\)[^()]*)*/I Capturing subpattern count = 0 No options No first char No need char (this(and)that 0: (this(and)that) 0: (this(and)that) (this(and)that)stuff 0: (this(and)that)stuff /[^()]*(?:\((?>(?R))\)[^()]*)*/I Capturing subpattern count = 0 No options No first char No need char (this(and)that 0: (this(and)that) 0: (this(and)that) /[^()]*(?:\((?R)\))*[^()]*/I Capturing subpattern count = 0 No options No first char No need char (this(and)that 0: (this(and)that) 0: (this(and)that) /(?:\((?R)\))*[^()]*/I Capturing subpattern count = 0 No options No first char No need char (this(and)that 0: (this(and)that) 0: ((this)) 0: ((this)) /(?:\((?R)\))|[^()]*/I Capturing subpattern count = 0 No options No first char No need char (this(and)that 0: (this(and)that) 0: (this) 0: (this) ((this)) 0: ((this)) /\x{0000ff}/I Capturing subpattern count = 0 No options First char = \xff No need char /^((?Pa1)|(?Pa2)b)/I Failed: two named subpatterns have the same name at offset 17 /^((?Pa1)|(?Pa2)b)/IJ 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: 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 /^(?Pa)(?Pb)/IJ 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 /^(?Pa)(?Pb)|cd/IJ 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 /^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ 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: 2: 3: ef 4: gh C ef (2) A /^((?Pa1)|(?Pa2)b)/IJ 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: 3: a2 G a2 (2) A ** Failers No match a1b\GZ\GA no parentheses with name "Z" 0: a1 1: a1 2: a1 get substring Z failed -7 G a1 (2) A /^(?Pa)(?Pb)/IJ 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 /^(?Pa)(?Pb)|cd/IJ 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 get substring A failed -7 /^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ 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: 2: 3: ef 4: gh G ef (2) A /(?J)^((?Pa1)|(?Pa2)b)/I Capturing subpattern count = 3 Named capturing subpatterns: A 2 A 3 Options: anchored dupnames Duplicate name status changes 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: 3: a2 C a2 (2) A /^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I Failed: two named subpatterns have the same name at offset 37 / 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. /Ix Capturing subpattern count = 1 Options: extended First char = 'I' Need char = 'e' /^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I Capturing subpattern count = 4 Named capturing subpatterns: A 1 B 2 B 3 C 4 Options: anchored Duplicate name status changes 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 /^(?Pa)?(?(A)a|b)/I 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)(?PX))+/I 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))+/I Failed: reference to non-existent subpattern at offset 9 /(?:(?(ZA)a|b)(?PX))+/I Failed: reference to non-existent subpattern at offset 9 /(?:(?(ZZ)a|b)(?(ZZ)a|b)(?PX))+/I 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\))\\(?PX))+/I 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 /(?PX|Y))+/I 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)(?PX|Y))+/I 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 /\s*,\s*/IS Capturing subpattern count = 0 No options No first char Need char = ',' Subject length lower bound = 1 Starting byte set: \x09 \x0a \x0c \x0d \x20 , \x0b,\x0b 0: , \x0c,\x0d 0: \x0c,\x0d /^abc/Im Capturing subpattern count = 0 Options: multiline First char at start or follows newline Need char = 'c' xyz\nabc 0: abc xyz\nabc\ 0: abc xyz\r\nabc\ 0: abc xyz\rabc\ 0: abc xyz\r\nabc\ 0: abc ** Failers No match xyz\nabc\ No match xyz\r\nabc\ No match xyz\nabc\ No match xyz\rabc\ No match xyz\rabc\ No match /abc$/Im Capturing subpattern count = 0 Options: multiline Forced newline sequence: LF First char = 'a' Need char = 'c' xyzabc 0: abc xyzabc\n 0: abc xyzabc\npqr 0: abc xyzabc\r\ 0: abc xyzabc\rpqr\ 0: abc xyzabc\r\n\ 0: abc xyzabc\r\npqr\ 0: abc ** Failers No match xyzabc\r No match xyzabc\rpqr No match xyzabc\r\n No match xyzabc\r\npqr No match /^abc/Im 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\ 0: abc ** Failers No match xyz\nabcdef No match /^abc/Im 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\ 0: abc ** Failers No match xyz\rabcdef No match /^abc/Im 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\ 0: abc ** Failers No match xyz\rabcdef No match /^abc/Im Unknown newline type at: /abc/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' xyz\rabc\ Unknown newline type at: abc 0: abc /.*/I Capturing subpattern count = 0 Options: Forced newline sequence: LF 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 \abc\ndef 0: abc\x0adef \abc\rdef 0: abc \abc\r\ndef 0: abc \abc\ndef 0: abc\x0adef \abc\rdef 0: abc\x0ddef \abc\r\ndef 0: abc /\w+(.)(.)?def/Is Capturing subpattern count = 2 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|.)*?[*]/)*)+I Capturing subpattern count = 1 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 */ /(?P25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?P>B)){3}/I Capturing subpattern count = 1 Named capturing subpatterns: B 1 No options No first char Need char = '.' /()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() ()()()()()()()()()()()()()()()()()()()() (.(.))/Ix Capturing subpattern count = 102 Options: extended No first char No need char XY\O400 0: XY 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: XY 102: Y /(a*b|(?i:c*(?-i)d))/IS Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: C a b c d /()[ab]xyz/IS Capturing subpattern count = 1 No options No first char Need char = 'z' Subject length lower bound = 4 Starting byte set: a b /(|)[ab]xyz/IS Capturing subpattern count = 1 No options No first char Need char = 'z' Subject length lower bound = 4 Starting byte set: a b /(|c)[ab]xyz/IS Capturing subpattern count = 1 No options No first char Need char = 'z' Subject length lower bound = 4 Starting byte set: a b c /(|c?)[ab]xyz/IS Capturing subpattern count = 1 No options No first char Need char = 'z' Subject length lower bound = 4 Starting byte set: a b c /(d?|c?)[ab]xyz/IS Capturing subpattern count = 1 No options No first char Need char = 'z' Subject length lower bound = 4 Starting byte set: a b c d /(d?|c)[ab]xyz/IS Capturing subpattern count = 1 No options No first char Need char = 'z' Subject length lower bound = 4 Starting byte set: a b c d /^a*b\d/DZ ------------------------------------------------------------------ Bra ^ a*+ b \d Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char Need char = 'b' /^a*+b\d/DZ ------------------------------------------------------------------ Bra ^ a*+ b \d Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char Need char = 'b' /^a*?b\d/DZ ------------------------------------------------------------------ Bra ^ a*+ b \d Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char Need char = 'b' /^a+A\d/DZ ------------------------------------------------------------------ Bra ^ a++ A \d Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char Need char = 'A' aaaA5 0: aaaA5 ** Failers No match aaaa5 No match /^a*A\d/IiDZ ------------------------------------------------------------------ Bra ^ /i a* /i A \d Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored caseless No first char Need char = 'A' (caseless) aaaA5 0: aaaA5 aaaa5 0: aaaa5 /(a*|b*)[cd]/IS Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b c d /(a+|b*)[cd]/IS Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b c d /(a*|b+)[cd]/IS Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: a b c d /(a+|b+)[cd]/IS Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 2 Starting byte set: a b /(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( ((( a )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) ))) /Ix Capturing subpattern count = 203 Options: extended First char = 'a' No need char large nest Matched, but too many substrings 0: a 1: a 2: a 3: a 4: a 5: a 6: a 7: a 8: a 9: a 10: a 11: a 12: a 13: a 14: a /a*\d/BZ ------------------------------------------------------------------ Bra a*+ \d Ket End ------------------------------------------------------------------ /a*\D/BZ ------------------------------------------------------------------ Bra a* \D Ket End ------------------------------------------------------------------ /0*\d/BZ ------------------------------------------------------------------ Bra 0* \d Ket End ------------------------------------------------------------------ /0*\D/BZ ------------------------------------------------------------------ Bra 0*+ \D Ket End ------------------------------------------------------------------ /a*\s/BZ ------------------------------------------------------------------ Bra a*+ \s Ket End ------------------------------------------------------------------ /a*\S/BZ ------------------------------------------------------------------ Bra a* \S Ket End ------------------------------------------------------------------ / *\s/BZ ------------------------------------------------------------------ Bra * \s Ket End ------------------------------------------------------------------ / *\S/BZ ------------------------------------------------------------------ Bra *+ \S Ket End ------------------------------------------------------------------ /a*\w/BZ ------------------------------------------------------------------ Bra a* \w Ket End ------------------------------------------------------------------ /a*\W/BZ ------------------------------------------------------------------ Bra a*+ \W Ket End ------------------------------------------------------------------ /=*\w/BZ ------------------------------------------------------------------ Bra =*+ \w Ket End ------------------------------------------------------------------ /=*\W/BZ ------------------------------------------------------------------ Bra =* \W Ket End ------------------------------------------------------------------ /\d*a/BZ ------------------------------------------------------------------ Bra \d*+ a Ket End ------------------------------------------------------------------ /\d*2/BZ ------------------------------------------------------------------ Bra \d* 2 Ket End ------------------------------------------------------------------ /\d*\d/BZ ------------------------------------------------------------------ Bra \d* \d Ket End ------------------------------------------------------------------ /\d*\D/BZ ------------------------------------------------------------------ Bra \d*+ \D Ket End ------------------------------------------------------------------ /\d*\s/BZ ------------------------------------------------------------------ Bra \d*+ \s Ket End ------------------------------------------------------------------ /\d*\S/BZ ------------------------------------------------------------------ Bra \d* \S Ket End ------------------------------------------------------------------ /\d*\w/BZ ------------------------------------------------------------------ Bra \d* \w Ket End ------------------------------------------------------------------ /\d*\W/BZ ------------------------------------------------------------------ Bra \d*+ \W Ket End ------------------------------------------------------------------ /\D*a/BZ ------------------------------------------------------------------ Bra \D* a Ket End ------------------------------------------------------------------ /\D*2/BZ ------------------------------------------------------------------ Bra \D*+ 2 Ket End ------------------------------------------------------------------ /\D*\d/BZ ------------------------------------------------------------------ Bra \D*+ \d Ket End ------------------------------------------------------------------ /\D*\D/BZ ------------------------------------------------------------------ Bra \D* \D Ket End ------------------------------------------------------------------ /\D*\s/BZ ------------------------------------------------------------------ Bra \D* \s Ket End ------------------------------------------------------------------ /\D*\S/BZ ------------------------------------------------------------------ Bra \D* \S Ket End ------------------------------------------------------------------ /\D*\w/BZ ------------------------------------------------------------------ Bra \D* \w Ket End ------------------------------------------------------------------ /\D*\W/BZ ------------------------------------------------------------------ Bra \D* \W Ket End ------------------------------------------------------------------ /\s*a/BZ ------------------------------------------------------------------ Bra \s*+ a Ket End ------------------------------------------------------------------ /\s*2/BZ ------------------------------------------------------------------ Bra \s*+ 2 Ket End ------------------------------------------------------------------ /\s*\d/BZ ------------------------------------------------------------------ Bra \s*+ \d Ket End ------------------------------------------------------------------ /\s*\D/BZ ------------------------------------------------------------------ Bra \s* \D Ket End ------------------------------------------------------------------ /\s*\s/BZ ------------------------------------------------------------------ Bra \s* \s Ket End ------------------------------------------------------------------ /\s*\S/BZ ------------------------------------------------------------------ Bra \s*+ \S Ket End ------------------------------------------------------------------ /\s*\w/BZ ------------------------------------------------------------------ Bra \s*+ \w Ket End ------------------------------------------------------------------ /\s*\W/BZ ------------------------------------------------------------------ Bra \s* \W Ket End ------------------------------------------------------------------ /\S*a/BZ ------------------------------------------------------------------ Bra \S* a Ket End ------------------------------------------------------------------ /\S*2/BZ ------------------------------------------------------------------ Bra \S* 2 Ket End ------------------------------------------------------------------ /\S*\d/BZ ------------------------------------------------------------------ Bra \S* \d Ket End ------------------------------------------------------------------ /\S*\D/BZ ------------------------------------------------------------------ Bra \S* \D Ket End ------------------------------------------------------------------ /\S*\s/BZ ------------------------------------------------------------------ Bra \S*+ \s Ket End ------------------------------------------------------------------ /\S*\S/BZ ------------------------------------------------------------------ Bra \S* \S Ket End ------------------------------------------------------------------ /\S*\w/BZ ------------------------------------------------------------------ Bra \S* \w Ket End ------------------------------------------------------------------ /\S*\W/BZ ------------------------------------------------------------------ Bra \S* \W Ket End ------------------------------------------------------------------ /\w*a/BZ ------------------------------------------------------------------ Bra \w* a Ket End ------------------------------------------------------------------ /\w*2/BZ ------------------------------------------------------------------ Bra \w* 2 Ket End ------------------------------------------------------------------ /\w*\d/BZ ------------------------------------------------------------------ Bra \w* \d Ket End ------------------------------------------------------------------ /\w*\D/BZ ------------------------------------------------------------------ Bra \w* \D Ket End ------------------------------------------------------------------ /\w*\s/BZ ------------------------------------------------------------------ Bra \w*+ \s Ket End ------------------------------------------------------------------ /\w*\S/BZ ------------------------------------------------------------------ Bra \w* \S Ket End ------------------------------------------------------------------ /\w*\w/BZ ------------------------------------------------------------------ Bra \w* \w Ket End ------------------------------------------------------------------ /\w*\W/BZ ------------------------------------------------------------------ Bra \w*+ \W Ket End ------------------------------------------------------------------ /\W*a/BZ ------------------------------------------------------------------ Bra \W*+ a Ket End ------------------------------------------------------------------ /\W*2/BZ ------------------------------------------------------------------ Bra \W*+ 2 Ket End ------------------------------------------------------------------ /\W*\d/BZ ------------------------------------------------------------------ Bra \W*+ \d Ket End ------------------------------------------------------------------ /\W*\D/BZ ------------------------------------------------------------------ Bra \W* \D Ket End ------------------------------------------------------------------ /\W*\s/BZ ------------------------------------------------------------------ Bra \W* \s Ket End ------------------------------------------------------------------ /\W*\S/BZ ------------------------------------------------------------------ Bra \W* \S Ket End ------------------------------------------------------------------ /\W*\w/BZ ------------------------------------------------------------------ Bra \W*+ \w Ket End ------------------------------------------------------------------ /\W*\W/BZ ------------------------------------------------------------------ Bra \W* \W Ket End ------------------------------------------------------------------ /[^a]+a/BZ ------------------------------------------------------------------ Bra [^a]++ a Ket End ------------------------------------------------------------------ /[^a]+a/BZi ------------------------------------------------------------------ Bra /i [^a]++ /i a Ket End ------------------------------------------------------------------ /[^a]+A/BZi ------------------------------------------------------------------ Bra /i [^a]++ /i A Ket End ------------------------------------------------------------------ /[^a]+b/BZ ------------------------------------------------------------------ Bra [^a]+ b Ket End ------------------------------------------------------------------ /[^a]+\d/BZ ------------------------------------------------------------------ Bra [^a]+ \d Ket End ------------------------------------------------------------------ /a*[^a]/BZ ------------------------------------------------------------------ Bra a* [^a] Ket End ------------------------------------------------------------------ /(?Px)(?Py)/I Capturing subpattern count = 2 Named capturing subpatterns: abc 1 xyz 2 No options First char = 'x' Need char = 'y' xy\Cabc\Cxyz 0: xy 1: x 2: y C x (1) abc C y (1) xyz /(?x)(?'xyz'y)/I Capturing subpattern count = 2 Named capturing subpatterns: abc 1 xyz 2 No options First char = 'x' Need char = 'y' xy\Cabc\Cxyz 0: xy 1: x 2: y C x (1) abc C y (1) xyz /(?x)(?'xyz>y)/I Failed: syntax error in subpattern name (missing terminator) at offset 15 /(?P'abc'x)(?Py)/I Failed: unrecognized character after (?P at offset 3 /^(?:(?(ZZ)a|b)(?X))+/ bXaX 0: bXaX 1: X bXbX 0: bX 1: X ** Failers No match aXaX No match aXbX No match /^(?P>abc)(?xxx)/ Failed: reference to non-existent subpattern at offset 8 /^(?P>abc)(?x|y)/ xx 0: xx 1: x xy 0: xy 1: y yy 0: yy 1: y yx 0: yx 1: x /^(?P>abc)(?Px|y)/ xx 0: xx 1: x xy 0: xy 1: y yy 0: yy 1: y yx 0: yx 1: x /^((?(abc)a|b)(?x|y))+/ bxay 0: bxay 1: ay 2: y bxby 0: bx 1: bx 2: x ** Failers No match axby No match /^(((?P=abc)|X)(?x|y))+/ XxXxxx 0: XxXxxx 1: xx 2: x 3: x XxXyyx 0: XxXyyx 1: yx 2: y 3: x XxXyxx 0: XxXy 1: Xy 2: X 3: y ** Failers No match x No match /^(?1)(abc)/ abcabc 0: abcabc 1: abc /^(?:(?:\1|X)(a|b))+/ Xaaa 0: Xaaa 1: a Xaba 0: Xa 1: a /^[\E\Qa\E-\Qz\E]+/BZ ------------------------------------------------------------------ Bra ^ [a-z]+ Ket End ------------------------------------------------------------------ /^[a\Q]bc\E]/BZ ------------------------------------------------------------------ Bra ^ [\]a-c] Ket End ------------------------------------------------------------------ /^[a-\Q\E]/BZ ------------------------------------------------------------------ Bra ^ [\-a] Ket End ------------------------------------------------------------------ /^(?P>abc)[()](?)/BZ ------------------------------------------------------------------ Bra ^ Recurse [()] CBra 1 Ket Ket End ------------------------------------------------------------------ /^((?(abc)y)[()](?Px))+/BZ ------------------------------------------------------------------ Bra ^ CBra 1 Cond 2 Cond nref y Ket [()] CBra 2 x Ket KetRmax Ket End ------------------------------------------------------------------ (xy)x 0: (xy)x 1: y)x 2: x /^(?P>abc)\Q()\E(?)/BZ ------------------------------------------------------------------ Bra ^ Recurse () CBra 1 Ket Ket End ------------------------------------------------------------------ /^(?P>abc)[a\Q(]\E(](?)/BZ ------------------------------------------------------------------ Bra ^ Recurse [(\]a] CBra 1 Ket Ket End ------------------------------------------------------------------ /^(?P>abc) # this is (a comment) (?)/BZx ------------------------------------------------------------------ Bra ^ Recurse CBra 1 Ket Ket End ------------------------------------------------------------------ /^\W*(?:(?(?.)\W*(?&one)\W*\k|)|(?(?.)\W*(?&three)\W*\k'four'|\W*.\W*))\W*$/Ii Capturing subpattern count = 4 Max back reference = 4 Named capturing subpatterns: four 4 one 1 three 3 two 2 Options: anchored caseless No first char No need char 1221 0: 1221 1: 1221 2: 1 Satan, oscillate my metallic sonatas! 0: Satan, oscillate my metallic sonatas! 1: 2: 3: Satan, oscillate my metallic sonatas 4: S A man, a plan, a canal: Panama! 0: A man, a plan, a canal: Panama! 1: 2: 3: A man, a plan, a canal: Panama 4: A Able was I ere I saw Elba. 0: Able was I ere I saw Elba. 1: 2: 3: Able was I ere I saw Elba 4: A *** Failers No match The quick brown fox No match /(?=(\w+))\1:/I Capturing subpattern count = 1 Max back reference = 1 No options No first char Need char = ':' abcd: 0: abcd: 1: abcd /(?=(?'abc'\w+))\k:/I Capturing subpattern count = 1 Max back reference = 1 Named capturing subpatterns: abc 1 No options No first char Need char = ':' abcd: 0: abcd: 1: abcd /(?'abc'a|b)(?d|e)\k{2}/J adaa 0: adaa 1: a 2: d ** Failers No match addd No match adbb No match /(?'abc'a|b)(?d|e)(?&abc){2}/J bdaa 0: bdaa 1: b 2: d bdab 0: bdab 1: b 2: d ** Failers No match bddd No match /(?( (?'B' abc (?(R) (?(R&A)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x abcabc1Xabc2XabcXabcabc 0: abcabc1Xabc2XabcX 1: abcabc1Xabc2XabcX 2: abcabc1Xabc2XabcX /(? (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x Failed: reference to non-existent subpattern at offset 29 /(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x abcabc1Xabc2XabcXabcabc 0: abcabc1Xabc2XabcX 1: abcabc1Xabc2XabcX 2: abcabc1Xabc2XabcX /^(?(DEFINE) abc | xyz ) /x Failed: DEFINE group contains more than one branch at offset 22 /(?(DEFINE) abc) xyz/xI Capturing subpattern count = 0 Options: extended First char = 'x' Need char = 'z' /(a|)*\d/ \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 Matched, but too many substrings /^a.b/ a\rb 0: a\x0db a\nb\ 0: a\x0ab a\x85b\ 0: a\x85b ** Failers No match a\nb No match a\nb\ No match a\rb\ No match a\rb\ No match a\x85b\ No match a\rb\ No match /^abc./mgx abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc7 /abc.$/mgx abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc7 abc9 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc9 /a/ /a/ Failed: inconsistent NEWLINE options at offset 0 /^a\Rb/ a\nb 0: a\x0ab a\rb 0: a\x0db a\r\nb 0: a\x0d\x0ab a\x0bb 0: a\x0bb a\x0cb 0: a\x0cb a\x85b 0: a\x85b ** Failers No match a\n\rb No match /^a\R*b/ ab 0: ab a\nb 0: a\x0ab a\rb 0: a\x0db a\r\nb 0: a\x0d\x0ab a\x0bb 0: a\x0bb a\x0cb 0: a\x0cb a\x85b 0: a\x85b a\n\rb 0: a\x0a\x0db a\n\r\x85\x0cb 0: a\x0a\x0d\x85\x0cb /^a\R+b/ a\nb 0: a\x0ab a\rb 0: a\x0db a\r\nb 0: a\x0d\x0ab a\x0bb 0: a\x0bb a\x0cb 0: a\x0cb a\x85b 0: a\x85b a\n\rb 0: a\x0a\x0db a\n\r\x85\x0cb 0: a\x0a\x0d\x85\x0cb ** Failers No match ab No match /^a\R{1,3}b/ a\nb 0: a\x0ab a\n\rb 0: a\x0a\x0db a\n\r\x85b 0: a\x0a\x0d\x85b a\r\n\r\nb 0: a\x0d\x0a\x0d\x0ab a\r\n\r\n\r\nb 0: a\x0d\x0a\x0d\x0a\x0d\x0ab a\n\r\n\rb 0: a\x0a\x0d\x0a\x0db a\n\n\r\nb 0: a\x0a\x0a\x0d\x0ab ** Failers No match a\n\n\n\rb No match a\r No match /^a[\R]b/ aRb 0: aRb ** Failers No match a\nb No match /(?&abc)X(?P)/I Capturing subpattern count = 1 Named capturing subpatterns: abc 1 No options No first char Need char = 'P' abcPXP123 0: PXP 1: P /(?1)X(?P)/I Capturing subpattern count = 1 Named capturing subpatterns: abc 1 No options No first char Need char = 'P' abcPXP123 0: PXP 1: P /(?:a(?&abc)b)*(?x)/ 123axbaxbaxbx456 0: axbaxbaxbx 1: x 123axbaxbaxb456 0: x 1: x /(?:a(?&abc)b){1,5}(?x)/ 123axbaxbaxbx456 0: axbaxbaxbx 1: x /(?:a(?&abc)b){2,5}(?x)/ 123axbaxbaxbx456 0: axbaxbaxbx 1: x /(?:a(?&abc)b){2,}(?x)/ 123axbaxbaxbx456 0: axbaxbaxbx 1: x /(abc)(?i:(?1))/ defabcabcxyz 0: abcabc 1: abc DEFabcABCXYZ No match /(abc)(?:(?i)(?1))/ defabcabcxyz 0: abcabc 1: abc DEFabcABCXYZ No match /^(a)\g-2/ Failed: reference to non-existent subpattern at offset 7 /^(a)\g/ Failed: a numbered reference must not be zero at offset 5 /^(a)\g{0}/ Failed: a numbered reference must not be zero at offset 8 /^(a)\g{3/ Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 8 /^(a)\g{4a}/ Failed: reference to non-existent subpattern at offset 9 /^a.b/ a\rb 0: a\x0db *** Failers No match a\nb No match /.+foo/ afoo 0: afoo ** Failers No match \r\nfoo No match \nfoo No match /.+foo/ afoo 0: afoo \nfoo 0: \x0afoo ** Failers No match \r\nfoo No match /.+foo/ afoo 0: afoo ** Failers No match \nfoo No match \r\nfoo No match /.+foo/s afoo 0: afoo \r\nfoo 0: \x0d\x0afoo \nfoo 0: \x0afoo /^$/mg abc\r\rxyz 0: abc\n\rxyz 0: ** Failers No match abc\r\nxyz No match /(?m)^$/g+ abc\r\n\r\n 0: 0+ \x0d\x0a /(?m)^$|^\r\n/g+ abc\r\n\r\n 0: 0+ \x0d\x0a 0: \x0d\x0a 0+ /(?m)$/g+ abc\r\n\r\n 0: 0+ \x0d\x0a\x0d\x0a 0: 0+ \x0d\x0a 0: 0+ /abc.$/mgx abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 0: abc1 0: abc4 0: abc5 0: abc9 /^X/m XABC 0: X ** Failers No match XABC\B No match /(ab|c)(?-1)/BZ ------------------------------------------------------------------ Bra CBra 1 ab Alt c Ket Recurse Ket End ------------------------------------------------------------------ abc 0: abc 1: ab /xy(?+1)(abc)/BZ ------------------------------------------------------------------ Bra xy Recurse CBra 1 abc Ket Ket End ------------------------------------------------------------------ xyabcabc 0: xyabcabc 1: abc ** Failers No match xyabc No match /x(?-0)y/ Failed: a numbered reference must not be zero at offset 5 /x(?-1)y/ Failed: reference to non-existent subpattern at offset 5 /x(?+0)y/ Failed: a numbered reference must not be zero at offset 5 /x(?+1)y/ Failed: reference to non-existent subpattern at offset 5 /^(abc)?(?(-1)X|Y)/BZ ------------------------------------------------------------------ Bra ^ Brazero CBra 1 abc Ket Cond 1 Cond ref X Alt Y Ket Ket End ------------------------------------------------------------------ abcX 0: abcX 1: abc Y 0: Y ** Failers No match abcY No match /^((?(+1)X|Y)(abc))+/BZ ------------------------------------------------------------------ Bra ^ CBra 1 Cond 2 Cond ref X Alt Y Ket CBra 2 abc Ket KetRmax Ket End ------------------------------------------------------------------ YabcXabc 0: YabcXabc 1: Xabc 2: abc YabcXabcXabc 0: YabcXabcXabc 1: Xabc 2: abc ** Failers No match XabcXabc No match /(?(-1)a)/BZ Failed: reference to non-existent subpattern at offset 6 /((?(-1)a))/BZ ------------------------------------------------------------------ Bra CBra 1 Cond 1 Cond ref a Ket Ket Ket End ------------------------------------------------------------------ /((?(-2)a))/BZ Failed: reference to non-existent subpattern at offset 7 /^(?(+1)X|Y)(.)/BZ ------------------------------------------------------------------ Bra ^ Cond 1 Cond ref X Alt Y Ket CBra 1 Any Ket Ket End ------------------------------------------------------------------ Y! 0: Y! 1: ! /(?tom|bon)-\k{A}/ tom-tom 0: tom-tom 1: tom bon-bon 0: bon-bon 1: bon ** Failers No match tom-bon No match /\g{A/ Failed: syntax error in subpattern name (missing terminator) at offset 4 /(?|(abc)|(xyz))/BZ ------------------------------------------------------------------ Bra Bra CBra 1 abc Ket Alt CBra 1 xyz Ket Ket Ket End ------------------------------------------------------------------ >abc< 0: abc 1: abc >xyz< 0: xyz 1: xyz /(x)(?|(abc)|(xyz))(x)/BZ ------------------------------------------------------------------ Bra CBra 1 x Ket Bra CBra 2 abc Ket Alt CBra 2 xyz Ket Ket CBra 3 x Ket Ket End ------------------------------------------------------------------ xabcx 0: xabcx 1: x 2: abc 3: x xxyzx 0: xxyzx 1: x 2: xyz 3: x /(x)(?|(abc)(pqr)|(xyz))(x)/BZ ------------------------------------------------------------------ Bra CBra 1 x Ket Bra CBra 2 abc Ket CBra 3 pqr Ket Alt CBra 2 xyz Ket Ket CBra 4 x Ket Ket End ------------------------------------------------------------------ xabcpqrx 0: xabcpqrx 1: x 2: abc 3: pqr 4: x xxyzx 0: xxyzx 1: x 2: xyz 3: 4: x /\H++X/BZ ------------------------------------------------------------------ Bra \H++ X Ket End ------------------------------------------------------------------ ** Failers No match XXXX No match /\H+\hY/BZ ------------------------------------------------------------------ Bra \H++ \h Y Ket End ------------------------------------------------------------------ XXXX Y 0: XXXX Y /\H+ Y/BZ ------------------------------------------------------------------ Bra \H++ Y Ket End ------------------------------------------------------------------ /\h+A/BZ ------------------------------------------------------------------ Bra \h++ A Ket End ------------------------------------------------------------------ /\v*B/BZ ------------------------------------------------------------------ Bra \v*+ B Ket End ------------------------------------------------------------------ /\V+\x0a/BZ ------------------------------------------------------------------ Bra \V++ \x0a Ket End ------------------------------------------------------------------ /A+\h/BZ ------------------------------------------------------------------ Bra A++ \h Ket End ------------------------------------------------------------------ / *\H/BZ ------------------------------------------------------------------ Bra *+ \H Ket End ------------------------------------------------------------------ /A*\v/BZ ------------------------------------------------------------------ Bra A*+ \v Ket End ------------------------------------------------------------------ /\x0b*\V/BZ ------------------------------------------------------------------ Bra \x0b*+ \V Ket End ------------------------------------------------------------------ /\d+\h/BZ ------------------------------------------------------------------ Bra \d++ \h Ket End ------------------------------------------------------------------ /\d*\v/BZ ------------------------------------------------------------------ Bra \d*+ \v Ket End ------------------------------------------------------------------ /S+\h\S+\v/BZ ------------------------------------------------------------------ Bra S++ \h \S++ \v Ket End ------------------------------------------------------------------ /\w{3,}\h\w+\v/BZ ------------------------------------------------------------------ Bra \w{3} \w*+ \h \w++ \v Ket End ------------------------------------------------------------------ /\h+\d\h+\w\h+\S\h+\H/BZ ------------------------------------------------------------------ Bra \h++ \d \h++ \w \h++ \S \h++ \H Ket End ------------------------------------------------------------------ /\v+\d\v+\w\v+\S\v+\V/BZ ------------------------------------------------------------------ Bra \v++ \d \v++ \w \v+ \S \v++ \V Ket End ------------------------------------------------------------------ /\H+\h\H+\d/BZ ------------------------------------------------------------------ Bra \H++ \h \H+ \d Ket End ------------------------------------------------------------------ /\V+\v\V+\w/BZ ------------------------------------------------------------------ Bra \V++ \v \V+ \w Ket End ------------------------------------------------------------------ /\( (?: [^()]* | (?R) )* \)/x \J1024(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) 0: (0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) /[\E]AAA/ Failed: missing terminating ] for character class at offset 7 /[\Q\E]AAA/ Failed: missing terminating ] for character class at offset 9 /[^\E]AAA/ Failed: missing terminating ] for character class at offset 8 /[^\Q\E]AAA/ Failed: missing terminating ] for character class at offset 10 /[\E^]AAA/ Failed: missing terminating ] for character class at offset 8 /[\Q\E^]AAA/ Failed: missing terminating ] for character class at offset 10 /A(*PRUNE)B(*SKIP)C(*THEN)D(*COMMIT)E(*F)F(*FAIL)G(?!)H(*ACCEPT)I/BZ ------------------------------------------------------------------ Bra A *PRUNE B *SKIP C *THEN D *COMMIT E *FAIL F *FAIL G *FAIL H *ACCEPT I Ket End ------------------------------------------------------------------ /^a+(*FAIL)/C aaaaaa --->aaaaaa +0 ^ ^ +1 ^ a+ +3 ^ ^ (*FAIL) +3 ^ ^ (*FAIL) +3 ^ ^ (*FAIL) +3 ^ ^ (*FAIL) +3 ^ ^ (*FAIL) +3 ^^ (*FAIL) No match /a+b?c+(*FAIL)/C aaabccc --->aaabccc +0 ^ a+ +2 ^ ^ b? +4 ^ ^ c+ +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +4 ^ ^ c+ +2 ^ ^ b? +4 ^ ^ c+ +2 ^^ b? +4 ^^ c+ +0 ^ a+ +2 ^ ^ b? +4 ^ ^ c+ +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +4 ^ ^ c+ +2 ^^ b? +4 ^^ c+ +0 ^ a+ +2 ^^ b? +4 ^ ^ c+ +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +4 ^^ c+ No match /a+b?(*PRUNE)c+(*FAIL)/C aaabccc --->aaabccc +0 ^ a+ +2 ^ ^ b? +4 ^ ^ (*PRUNE) +12 ^ ^ c+ +14 ^ ^ (*FAIL) +14 ^ ^ (*FAIL) +14 ^ ^ (*FAIL) +0 ^ a+ +2 ^ ^ b? +4 ^ ^ (*PRUNE) +12 ^ ^ c+ +14 ^ ^ (*FAIL) +14 ^ ^ (*FAIL) +14 ^ ^ (*FAIL) +0 ^ a+ +2 ^^ b? +4 ^ ^ (*PRUNE) +12 ^ ^ c+ +14 ^ ^ (*FAIL) +14 ^ ^ (*FAIL) +14 ^ ^ (*FAIL) No match /a+b?(*COMMIT)c+(*FAIL)/C aaabccc --->aaabccc +0 ^ a+ +2 ^ ^ b? +4 ^ ^ (*COMMIT) +13 ^ ^ c+ +15 ^ ^ (*FAIL) +15 ^ ^ (*FAIL) +15 ^ ^ (*FAIL) No match /a+b?(*SKIP)c+(*FAIL)/C aaabcccaaabccc --->aaabcccaaabccc +0 ^ a+ +2 ^ ^ b? +4 ^ ^ (*SKIP) +11 ^ ^ c+ +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +0 ^ a+ +2 ^ ^ b? +4 ^ ^ (*SKIP) +11 ^ ^ c+ +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) No match /a+b?(*THEN)c+(*FAIL)/C aaabccc --->aaabccc +0 ^ a+ +2 ^ ^ b? +4 ^ ^ (*THEN) +11 ^ ^ c+ +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +0 ^ a+ +2 ^ ^ b? +4 ^ ^ (*THEN) +11 ^ ^ c+ +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +0 ^ a+ +2 ^^ b? +4 ^ ^ (*THEN) +11 ^ ^ c+ +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) +13 ^ ^ (*FAIL) No match /a(*MARK)b/ Failed: (*MARK) must have an argument at offset 7 /(?i:A{1,}\6666666666)/ Failed: number is too big at offset 19 /\g6666666666/ Failed: number is too big at offset 11 /[\g6666666666]/BZ ------------------------------------------------------------------ Bra [6g] Ket End ------------------------------------------------------------------ /(?1)\c[/ Failed: reference to non-existent subpattern at offset 3 /.+A/ \r\nA No match /\nA/ \r\nA 0: \x0aA /[\r\n]A/ \r\nA 0: \x0aA /(\r|\n)A/ \r\nA 0: \x0aA 1: \x0a /a(*CR)b/ Failed: (*VERB) not recognized at offset 5 /(*CR)a.b/ a\nb 0: a\x0ab ** Failers No match a\rb No match /(*CR)a.b/ a\nb 0: a\x0ab ** Failers No match a\rb No match /(*LF)a.b/ a\rb 0: a\x0db ** Failers No match a\nb No match /(*CRLF)a.b/ a\rb 0: a\x0db a\nb 0: a\x0ab ** Failers No match a\r\nb No match /(*ANYCRLF)a.b/ ** Failers No match a\rb No match a\nb No match a\r\nb No match /(*ANY)a.b/ ** Failers No match a\rb No match a\nb No match a\r\nb No match a\x85b No match /(*ANY).*/g abc\r\ndef 0: abc 0: 0: def 0: /(*ANYCRLF).*/g abc\r\ndef 0: abc 0: 0: def 0: /(*CRLF).*/g abc\r\ndef 0: abc 0: 0: def 0: /a\Rb/I Capturing subpattern count = 0 Options: bsr_anycrlf First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab ** Failers No match a\x85b No match a\x0bb No match /a\Rb/I Capturing subpattern count = 0 Options: bsr_unicode First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab a\x85b 0: a\x85b a\x0bb 0: a\x0bb ** Failers No match a\x85b\ No match a\x0bb\ No match /a\R?b/I Capturing subpattern count = 0 Options: bsr_anycrlf First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab ** Failers No match a\x85b No match a\x0bb No match /a\R?b/I Capturing subpattern count = 0 Options: bsr_unicode First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab a\x85b 0: a\x85b a\x0bb 0: a\x0bb ** Failers No match a\x85b\ No match a\x0bb\ No match /a\R{2,4}b/I Capturing subpattern count = 0 Options: bsr_anycrlf First char = 'a' Need char = 'b' a\r\n\nb 0: a\x0d\x0a\x0ab a\n\r\rb 0: a\x0a\x0d\x0db a\r\n\r\n\r\n\r\nb 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab ** Failers No match a\x85\85b No match a\x0b\0bb No match /a\R{2,4}b/I Capturing subpattern count = 0 Options: bsr_unicode First char = 'a' Need char = 'b' a\r\rb 0: a\x0d\x0db a\n\n\nb 0: a\x0a\x0a\x0ab a\r\n\n\r\rb 0: a\x0d\x0a\x0a\x0d\x0db a\x85\85b No match a\x0b\0bb No match ** Failers No match a\r\r\r\r\rb No match a\x85\85b\ No match a\x0b\0bb\ No match /(*BSR_ANYCRLF)a\Rb/I Capturing subpattern count = 0 Options: bsr_anycrlf First char = 'a' Need char = 'b' a\nb 0: a\x0ab a\rb 0: a\x0db /(*BSR_UNICODE)a\Rb/I Capturing subpattern count = 0 Options: bsr_unicode First char = 'a' Need char = 'b' a\x85b 0: a\x85b /(*BSR_ANYCRLF)(*CRLF)a\Rb/I Capturing subpattern count = 0 Options: bsr_anycrlf Forced newline sequence: CRLF First char = 'a' Need char = 'b' a\nb 0: a\x0ab a\rb 0: a\x0db /(*CRLF)(*BSR_UNICODE)a\Rb/I Capturing subpattern count = 0 Options: bsr_unicode Forced newline sequence: CRLF First char = 'a' Need char = 'b' a\x85b 0: a\x85b /(*CRLF)(*BSR_ANYCRLF)(*CR)ab/I Capturing subpattern count = 0 Options: bsr_anycrlf Forced newline sequence: CR First char = 'a' Need char = 'b' /(?)(?&)/ Failed: subpattern name expected at offset 9 /(?)(?&a)/ Failed: reference to non-existent subpattern at offset 12 /(?)(?&aaaaaaaaaaaaaaaaaaaaaaa)/ Failed: reference to non-existent subpattern at offset 32 /(?+-a)/ Failed: digit expected after (?+ at offset 3 /(?-+a)/ Failed: unrecognized character after (? or (?- at offset 3 /(?(-1))/ Failed: reference to non-existent subpattern at offset 6 /(?(+10))/ Failed: reference to non-existent subpattern at offset 7 /(?(10))/ Failed: reference to non-existent subpattern at offset 6 /(?(+2))()()/ /(?(2))()()/ /\k''/ Failed: subpattern name expected at offset 3 /\k<>/ Failed: subpattern name expected at offset 3 /\k{}/ Failed: subpattern name expected at offset 3 /\k/ Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 2 /\kabc/ Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 5 /(?P=)/ Failed: subpattern name expected at offset 4 /(?P>)/ Failed: subpattern name expected at offset 4 /(?!\w)(?R)/ Failed: recursive call could loop indefinitely at offset 9 /(?=\w)(?R)/ Failed: recursive call could loop indefinitely at offset 9 /(?x|y){0}z/ xzxx 0: xz yzyy 0: yz ** Failers No match xxz No match /(\3)(\1)(a)/ cat No match /(\3)(\1)(a)/ cat 0: a 1: 2: 3: a /TA]/ The ACTA] comes 0: TA] /TA]/ Failed: ] is an invalid data character in JavaScript compatibility mode at offset 2 /(?2)[]a()b](abc)/ Failed: reference to non-existent subpattern at offset 3 /(?2)[^]a()b](abc)/ Failed: reference to non-existent subpattern at offset 3 /(?1)[]a()b](abc)/ abcbabc 0: abcbabc 1: abc ** Failers No match abcXabc No match /(?1)[^]a()b](abc)/ abcXabc 0: abcXabc 1: abc ** Failers No match abcbabc No match /(?2)[]a()b](abc)(xyz)/ xyzbabcxyz 0: xyzbabcxyz 1: abc 2: xyz /(?&N)[]a(?)](?abc)/ Failed: reference to non-existent subpattern at offset 4 /(?&N)[]a(?)](abc)/ Failed: reference to non-existent subpattern at offset 4 /a[]b/ Failed: missing terminating ] for character class at offset 4 /a[^]b/ Failed: missing terminating ] for character class at offset 5 /a[]b/ ** Failers No match ab No match /a[]+b/ ** Failers No match ab No match /a[]*+b/ ** Failers No match ab No match /a[^]b/ aXb 0: aXb a\nb 0: a\x0ab ** Failers No match ab No match /a[^]+b/ aXb 0: aXb a\nX\nXb 0: a\x0aX\x0aXb ** Failers No match ab No match /a(?!)+b/ Failed: nothing to repeat at offset 5 /a(*FAIL)+b/ Failed: nothing to repeat at offset 8 /(abc|pqr|123){0}[xyz]/SI Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 1 Starting byte set: x y z /(?(?=.*b)b|^)/CI Capturing subpattern count = 0 Options: No first char No need char adc --->adc +0 ^ (?(?=.*b)b|^) +2 ^ (?=.*b) +5 ^ .* +7 ^ ^ b +7 ^ ^ b +7 ^^ b +7 ^ b +12 ^ ) +13 ^ 0: abc --->abc +0 ^ (?(?=.*b)b|^) +2 ^ (?=.*b) +5 ^ .* +7 ^ ^ b +7 ^ ^ b +7 ^^ b +8 ^ ^ ) +9 ^ b +0 ^ (?(?=.*b)b|^) +2 ^ (?=.*b) +5 ^ .* +7 ^ ^ b +7 ^^ b +7 ^ b +8 ^^ ) +9 ^ b +10 ^^ | +13 ^^ 0: b /(?(?=b).*b|^d)/I Capturing subpattern count = 0 No options No first char No need char /(?(?=.*b).*b|^d)/I Capturing subpattern count = 0 No options First char at start or follows newline No need char /xyz/C xyz --->xyz +0 ^ x +1 ^^ y +2 ^ ^ z +3 ^ ^ 0: xyz abcxyz --->abcxyz +0 ^ x +1 ^^ y +2 ^ ^ z +3 ^ ^ 0: xyz abcxyz\Y --->abcxyz +0 ^ x +0 ^ x +0 ^ x +0 ^ x +1 ^^ y +2 ^ ^ z +3 ^ ^ 0: xyz ** Failers No match abc No match abc\Y --->abc +0 ^ x +0 ^ x +0 ^ x +0 ^ x No match abcxypqr No match abcxypqr\Y --->abcxypqr +0 ^ x +0 ^ x +0 ^ x +0 ^ x +1 ^^ y +2 ^ ^ z +0 ^ x +0 ^ x +0 ^ x +0 ^ x +0 ^ x No match /(*NO_START_OPT)xyz/C abcxyz --->abcxyz +15 ^ x +15 ^ x +15 ^ x +15 ^ x +16 ^^ y +17 ^ ^ z +18 ^ ^ 0: xyz /xyz/CY abcxyz --->abcxyz +0 ^ x +0 ^ x +0 ^ x +0 ^ x +1 ^^ y +2 ^ ^ z +3 ^ ^ 0: xyz /^"((?(?=[a])[^"])|b)*"$/C "ab" --->"ab" +0 ^ ^ +1 ^ " +2 ^^ ((?(?=[a])[^"])|b)* +3 ^^ (?(?=[a])[^"]) +5 ^^ (?=[a]) +8 ^^ [a] +11 ^ ^ ) +12 ^^ [^"] +16 ^ ^ ) +17 ^ ^ | +3 ^ ^ (?(?=[a])[^"]) +5 ^ ^ (?=[a]) +8 ^ ^ [a] +21 ^ ^ " +18 ^ ^ b +19 ^ ^ ) +3 ^ ^ (?(?=[a])[^"]) +5 ^ ^ (?=[a]) +8 ^ ^ [a] +21 ^ ^ " +22 ^ ^ $ +23 ^ ^ 0: "ab" 1: /^"((?(?=[a])[^"])|b)*"$/ "ab" 0: "ab" 1: /^X(?5)(a)(?|(b)|(q))(c)(d)Y/ Failed: reference to non-existent subpattern at offset 5 /^X(?&N)(a)(?|(b)|(q))(c)(d)(?Y)/ XYabcdY 0: XYabcdY 1: a 2: b 3: c 4: d 5: Y /Xa{2,4}b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /Xa{2,4}?b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /Xa{2,4}+b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X\d{2,4}b/ X\P Partial match: X X3\P Partial match: X3 X33\P Partial match: X33 X333\P Partial match: X333 X3333\P Partial match: X3333 /X\d{2,4}?b/ X\P Partial match: X X3\P Partial match: X3 X33\P Partial match: X33 X333\P Partial match: X333 X3333\P Partial match: X3333 /X\d{2,4}+b/ X\P Partial match: X X3\P Partial match: X3 X33\P Partial match: X33 X333\P Partial match: X333 X3333\P Partial match: X3333 /X\D{2,4}b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X\D{2,4}?b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X\D{2,4}+b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X[abc]{2,4}b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X[abc]{2,4}?b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X[abc]{2,4}+b/ X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X[^a]{2,4}b/ X\P Partial match: X Xz\P Partial match: Xz Xzz\P Partial match: Xzz Xzzz\P Partial match: Xzzz Xzzzz\P Partial match: Xzzzz /X[^a]{2,4}?b/ X\P Partial match: X Xz\P Partial match: Xz Xzz\P Partial match: Xzz Xzzz\P Partial match: Xzzz Xzzzz\P Partial match: Xzzzz /X[^a]{2,4}+b/ X\P Partial match: X Xz\P Partial match: Xz Xzz\P Partial match: Xzz Xzzz\P Partial match: Xzzz Xzzzz\P Partial match: Xzzzz /(Y)X\1{2,4}b/ YX\P Partial match: YX YXY\P Partial match: YXY YXYY\P Partial match: YXYY YXYYY\P Partial match: YXYYY YXYYYY\P Partial match: YXYYYY /(Y)X\1{2,4}?b/ YX\P Partial match: YX YXY\P Partial match: YXY YXYY\P Partial match: YXYY YXYYY\P Partial match: YXYYY YXYYYY\P Partial match: YXYYYY /(Y)X\1{2,4}+b/ YX\P Partial match: YX YXY\P Partial match: YXY YXYY\P Partial match: YXYY YXYYY\P Partial match: YXYYY YXYYYY\P Partial match: YXYYYY /\++\KZ|\d+X|9+Y/ ++++123999\P Partial match: 123999 ++++123999Y\P 0: 999Y ++++Z1234\P 0: Z /Z(*F)/ Z\P No match ZA\P No match /Z(?!)/ Z\P No match ZA\P No match /dog(sbody)?/ dogs\P 0: dog dogs\P\P Partial match: dogs /dog(sbody)??/ dogs\P 0: dog dogs\P\P 0: dog /dog|dogsbody/ dogs\P 0: dog dogs\P\P 0: dog /dogsbody|dog/ dogs\P 0: dog dogs\P\P Partial match: dogs /\bthe cat\b/ the cat\P 0: the cat the cat\P\P Partial match: the cat /abc/ abc\P 0: abc abc\P\P 0: abc /abc\K123/ xyzabc123pqr 0: 123 xyzabc12\P Partial match: abc12 xyzabc12\P\P Partial match: abc12 /(?<=abc)123/ xyzabc123pqr 0: 123 xyzabc12\P Partial match: abc12 xyzabc12\P\P Partial match: abc12 /\babc\b/ +++abc+++ 0: abc +++ab\P Partial match: +ab +++ab\P\P Partial match: +ab /(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/BZ ------------------------------------------------------------------ Bra Recurse Recurse Cond Cond def CBra 1 < [^m] [^>] > [^<] Ket CBra 2 \w*+ Ket Ket Ket End ------------------------------------------------------------------ /(?&word)(?&element)(?(DEFINE)(?<[^\d][^>]>[^<])(?\w*+))/BZ ------------------------------------------------------------------ Bra Recurse Recurse Cond Cond def CBra 1 < [\x00-/:-\xff] (neg) [^>] > [^<] Ket CBra 2 \w*+ Ket Ket Ket End ------------------------------------------------------------------ /(ab)(x(y)z(cd(*ACCEPT)))pq/BZ ------------------------------------------------------------------ Bra CBra 1 ab Ket CBra 2 x CBra 3 y Ket z CBra 4 cd Close 4 Close 2 *ACCEPT Ket Ket pq Ket End ------------------------------------------------------------------ /abc\K/+ abcdef 0: 0+ def abcdef\N\N 0: 0+ def xyzabcdef\N\N 0: 0+ def ** Failers No match abcdef\N No match xyzabcdef\N No match /^(?:(?=abc)|abc\K)/+ abcdef 0: 0+ abcdef abcdef\N\N 0: 0+ def ** Failers No match abcdef\N No match /a?b?/+ xyz 0: 0+ xyz xyzabc 0: 0+ xyzabc xyzabc\N 0: ab 0+ c xyzabc\N\N 0: 0+ yzabc xyz\N\N 0: 0+ yz ** Failers 0: 0+ ** Failers xyz\N No match /^a?b?/+ xyz 0: 0+ xyz xyzabc 0: 0+ xyzabc ** Failers 0: 0+ ** Failers xyzabc\N No match xyzabc\N\N No match xyz\N\N No match xyz\N No match /^(?a|b\gc)/ aaaa 0: a 1: a bacxxx 0: bac 1: bac bbaccxxx 0: bbacc 1: bbacc bbbacccxx 0: bbbaccc 1: bbbaccc /^(?a|b\g'name'c)/ aaaa 0: a 1: a bacxxx 0: bac 1: bac bbaccxxx 0: bbacc 1: bbacc bbbacccxx 0: bbbaccc 1: bbbaccc /^(a|b\g<1>c)/ aaaa 0: a 1: a bacxxx 0: bac 1: bac bbaccxxx 0: bbacc 1: bbacc bbbacccxx 0: bbbaccc 1: bbbaccc /^(a|b\g'1'c)/ aaaa 0: a 1: a bacxxx 0: bac 1: bac bbaccxxx 0: bbacc 1: bbacc bbbacccxx 0: bbbaccc 1: bbbaccc /^(a|b\g'-1'c)/ aaaa 0: a 1: a bacxxx 0: bac 1: bac bbaccxxx 0: bbacc 1: bbacc bbbacccxx 0: bbbaccc 1: bbbaccc /(^(a|b\g<-1>c))/ aaaa 0: a 1: a 2: a bacxxx 0: bac 1: bac 2: bac bbaccxxx 0: bbacc 1: bbacc 2: bbacc bbbacccxx 0: bbbaccc 1: bbbaccc 2: bbbaccc /(?-i:\g)(?i:(?a))/ XaaX 0: aa 1: a XAAX 0: AA 1: A /(?i:\g)(?-i:(?a))/ XaaX 0: aa 1: a ** Failers No match XAAX No match /(?-i:\g<+1>)(?i:(a))/ XaaX 0: aa 1: a XAAX 0: AA 1: A /(?=(?(?#simplesyntax)\$(?[a-zA-Z_\x{7f}-\x{ff}][a-zA-Z0-9_\x{7f}-\x{ff}]*)(?:\[(?[a-zA-Z0-9_\x{7f}-\x{ff}]+|\$\g)\]|->\g(\(.*?\))?)?|(?#simple syntax withbraces)\$\{(?:\g(?\[(?:\g|'(?:\\.|[^'\\])*'|"(?:\g|\\.|[^"\\])*")\])?|\g|\$\{\g\})\}|(?#complexsyntax)\{(?\$(?\g(\g*|\(.*?\))?)(?:->\g)*|\$\g|\$\{\g\})\}))\{/ /(?a|b|c)\g*/ abc 0: abc 1: a accccbbb 0: accccbbb 1: a /^X(?7)(a)(?|(b)|(q)(r)(s))(c)(d)(Y)/ XYabcdY 0: XYabcdY 1: a 2: b 3: 4: 5: c 6: d 7: Y /(?<=b(?1)|zzz)(a)/ xbaax 0: a 1: a xzzzax 0: a 1: a /(a)(?<=b\1)/ Failed: lookbehind assertion is not fixed length at offset 10 /(a)(?<=b+(?1))/ Failed: lookbehind assertion is not fixed length at offset 13 /(a+)(?<=b(?1))/ Failed: lookbehind assertion is not fixed length at offset 14 /(a(?<=b(?1)))/ Failed: lookbehind assertion is not fixed length at offset 13 /(?<=b(?1))xyz/ Failed: reference to non-existent subpattern at offset 8 /(?<=b(?1))xyz(b+)pqrstuvew/ Failed: lookbehind assertion is not fixed length at offset 26 /(a|bc)\1/SI Capturing subpattern count = 1 Max back reference = 1 No options No first char No need char Subject length lower bound = 2 Starting byte set: a b /(a|bc)\1{2,3}/SI Capturing subpattern count = 1 Max back reference = 1 No options No first char No need char Subject length lower bound = 3 Starting byte set: a b /(a|bc)(?1)/SI Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 2 Starting byte set: a b /(a|b\1)(a|b\1)/SI Capturing subpattern count = 2 Max back reference = 1 No options No first char No need char Subject length lower bound = 2 Starting byte set: a b /(a|b\1){2}/SI Capturing subpattern count = 1 Max back reference = 1 No options No first char No need char Subject length lower bound = 2 Starting byte set: a b /(a|bbbb\1)(a|bbbb\1)/SI Capturing subpattern count = 2 Max back reference = 1 No options No first char No need char Subject length lower bound = 2 Starting byte set: a b /(a|bbbb\1){2}/SI Capturing subpattern count = 1 Max back reference = 1 No options No first char No need char Subject length lower bound = 2 Starting byte set: a b /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/SI Capturing subpattern count = 1 Options: anchored No first char Need char = ':' Subject length lower bound = 22 No set of starting bytes /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS Capturing subpattern count = 11 Options: caseless dotall First char = '<' Need char = '>' Subject length lower bound = 47 No set of starting bytes "(?>.*/)foo"SI Capturing subpattern count = 0 No options First char at start or follows newline Need char = 'o' Subject length lower bound = 4 No set of starting bytes /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /xSI Capturing subpattern count = 0 Options: extended No first char Need char = '-' Subject length lower bound = 8 No set of starting bytes /(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/iSI Capturing subpattern count = 1 Options: caseless No first char No need char Subject length lower bound = 1 Starting byte set: A B C a b c /(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/SI Capturing subpattern count = 0 No options No first char Need char = 'b' Subject length lower bound = 41 Starting byte set: c d /A)|(?
B))/I Capturing subpattern count = 1 Named capturing subpatterns: a 1 a 1 No options No first char No need char AB\Ca 0: A 1: A C A (1) a BA\Ca 0: B 1: B C B (1) a /(?|(?A)|(?B))/ Failed: different names for subpatterns of the same number are not allowed at offset 15 /(?:a(? (?')|(?")) | b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/JIx Capturing subpattern count = 6 Named capturing subpatterns: apostrophe 2 apostrophe 5 quote 1 quote 4 realquote 3 realquote 6 Options: extended dupnames No first char No need char a"aaaaa 0: a"aaaaa 1: " 2: 3: " b"aaaaa 0: b"aaaaa 1: 2: 3: 4: " 5: 6: " ** Failers No match b"11111 No match a"11111 No match /^(?|(a)(b)(c)(?d)|(?e)) (?('D')X|Y)/JDZx ------------------------------------------------------------------ Bra ^ Bra CBra 1 a Ket CBra 2 b Ket CBra 3 c Ket CBra 4 d Ket Alt CBra 1 e Ket Ket Cond 4 Cond nref X Alt Y Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 4 Named capturing subpatterns: D 4 D 1 Options: anchored extended dupnames No first char No need char abcdX 0: abcdX 1: a 2: b 3: c 4: d eX 0: eX 1: e ** Failers No match abcdY No match ey No match /(?a) (b)(c) (?d (?(R&A)$ | (?4)) )/JDZx ------------------------------------------------------------------ Bra CBra 1 a Ket CBra 2 b Ket CBra 3 c Ket CBra 4 d Cond Cond nrecurse 1 $ Alt Recurse Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 4 Named capturing subpatterns: A 1 A 4 Options: extended dupnames First char = 'a' Need char = 'd' abcdd 0: abcdd 1: a 2: b 3: c 4: dd ** Failers No match abcdde No match /abcd*/ xxxxabcd\P 0: abcd xxxxabcd\P\P Partial match: abcd /abcd*/i xxxxabcd\P 0: abcd xxxxabcd\P\P Partial match: abcd XXXXABCD\P 0: ABCD XXXXABCD\P\P Partial match: ABCD /abc\d*/ xxxxabc1\P 0: abc1 xxxxabc1\P\P Partial match: abc1 /(a)bc\1*/ xxxxabca\P 0: abca 1: a xxxxabca\P\P Partial match: abca /abc[de]*/ xxxxabcde\P 0: abcde xxxxabcde\P\P Partial match: abcde /-- This is not in the Perl >= 5.10 test because Perl seems currently to be broken and not behaving as specified in that it *does* bumpalong after hitting (*COMMIT). --/ /(?1)(A(*COMMIT)|B)D/ ABD 0: ABD 1: B XABD 0: ABD 1: B BAD 0: BAD 1: A ABXABD 0: ABD 1: B ** Failers No match ABX No match BAXBAD No match /(\3)(\1)(a)/ cat 0: a 1: 2: 3: a /(\3)(\1)(a)/SI Capturing subpattern count = 3 Max back reference = 3 Options: No first char Need char = 'a' Subject length lower bound = 1 No set of starting bytes cat 0: a 1: 2: 3: a /(\3)(\1)(a)/SI Capturing subpattern count = 3 Max back reference = 3 No options No first char Need char = 'a' Subject length lower bound = 3 No set of starting bytes cat No match /i(?(DEFINE)(?a))/SI Capturing subpattern count = 1 Named capturing subpatterns: s 1 No options First char = 'i' No need char Subject length lower bound = 1 No set of starting bytes i 0: i /()i(?(1)a)/SI Capturing subpattern count = 1 No options No first char Need char = 'i' Subject length lower bound = 1 Starting byte set: i ia 0: ia 1: /(?i)a(?-i)b|c/BZ ------------------------------------------------------------------ Bra /i a b Alt c Ket End ------------------------------------------------------------------ XabX 0: ab XAbX 0: Ab CcC 0: c ** Failers No match XABX No match /(?i)a(?s)b|c/BZ ------------------------------------------------------------------ Bra /i ab Alt /i c Ket End ------------------------------------------------------------------ /(?i)a(?s-i)b|c/BZ ------------------------------------------------------------------ Bra /i a b Alt c Ket End ------------------------------------------------------------------ /^(ab(c\1)d|x){2}$/BZ ------------------------------------------------------------------ Bra ^ Once CBra 1 ab CBra 2 c \1 Ket d Alt x Ket Ket Once CBra 1 ab CBra 2 c \1 Ket d Alt x Ket Ket $ Ket End ------------------------------------------------------------------ xabcxd 0: xabcxd 1: abcxd 2: cx /^(?&t)*+(?(DEFINE)(?.))$/BZ ------------------------------------------------------------------ Bra ^ Braposzero SBraPos Recurse KetRpos Cond Cond def CBra 1 Any Ket Ket $ Ket End ------------------------------------------------------------------ /^(?&t)*(?(DEFINE)(?.))$/BZ ------------------------------------------------------------------ Bra ^ Brazero Once Recurse KetRmax Cond Cond def CBra 1 Any Ket Ket $ Ket End ------------------------------------------------------------------ / -- The first four of these are not in the Perl >= 5.10 test because Perl documents that the use of \K in assertions is "not well defined". The last is here because Perl gives the match as "b" rather than "ab". I believe this to be a Perl bug. --/ /(?=a\Kb)ab/ ab 0: b /(?!a\Kb)ac/ ac 0: ac /^abc(?<=b\Kc)d/ abcd 0: cd /^abc(?a\Kb)z|(ab)/ ab 0: ab 1: ab /----------------------/ /(?P(?P0|)|(?P>L2)(?P>L1))/ Failed: recursive call could loop indefinitely at offset 31 /abc(*MARK:)pqr/ Failed: (*MARK) must have an argument at offset 10 /abc(*:)pqr/ Failed: (*MARK) must have an argument at offset 6 /abc(*FAIL:123)xyz/ Failed: an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) at offset 13 /--- This should, and does, fail. In Perl, it does not, which I think is a bug because replacing the B in the pattern by (B|D) does make it fail. ---/ /A(*COMMIT)B/+K ACABX No match /--- These should be different, but in Perl 5.11 are not, which I think is a bug in Perl. ---/ /A(*THEN)B|A(*THEN)C/K AC 0: AC /A(*PRUNE)B|A(*PRUNE)C/K AC No match /--- This should fail; the SKIP advances by one, but when we get to AC, the PRUNE kills it. Perl behaves differently. ---/ /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC No match, mark = A /--- Mark names can be duplicated. Perl doesn't give a mark for this one, though PCRE does. ---/ /^A(*:A)B|^X(*:A)Y/K ** Failers No match XAQQ No match, mark = A /--- COMMIT at the start of a pattern should be the same as an anchor. Perl optimizations defeat this. So does the PCRE optimization unless we disable it with \Y. ---/ /(*COMMIT)ABC/ ABCDEFG 0: ABC ** Failers No match DEFGABC\Y No match /^(ab (c+(*THEN)cd) | xyz)/x abcccd No match /^(ab (c+(*PRUNE)cd) | xyz)/x abcccd No match /^(ab (c+(*FAIL)cd) | xyz)/x abcccd No match /--- Perl 5.11 gets some of these wrong ---/ /(?>.(*ACCEPT))*?5/ abcde 0: a /(.(*ACCEPT))*?5/ abcde 0: a 1: a /(.(*ACCEPT))5/ abcde 0: a 1: a /(.(*ACCEPT))*5/ abcde 0: a 1: a /A\NB./BZ ------------------------------------------------------------------ Bra A Any B Any Ket End ------------------------------------------------------------------ ACBD 0: ACBD *** Failers No match A\nB No match ACB\n No match /A\NB./sBZ ------------------------------------------------------------------ Bra A Any B AllAny Ket End ------------------------------------------------------------------ ACBD 0: ACBD ACB\n 0: ACB\x0a *** Failers No match A\nB No match /A\NB/ A\nB 0: A\x0aB A\rB 0: A\x0dB ** Failers No match A\r\nB No match /\R+b/BZ ------------------------------------------------------------------ Bra \R++ b Ket End ------------------------------------------------------------------ /\R+\n/BZ ------------------------------------------------------------------ Bra \R+ \x0a Ket End ------------------------------------------------------------------ /\R+\d/BZ ------------------------------------------------------------------ Bra \R++ \d Ket End ------------------------------------------------------------------ /\d*\R/BZ ------------------------------------------------------------------ Bra \d*+ \R Ket End ------------------------------------------------------------------ /\s*\R/BZ ------------------------------------------------------------------ Bra \s* \R Ket End ------------------------------------------------------------------ \x20\x0a 0: \x0a \x20\x0d 0: \x0d \x20\x0d\x0a 0: \x0d\x0a /\S*\R/BZ ------------------------------------------------------------------ Bra \S*+ \R Ket End ------------------------------------------------------------------ a\x0a 0: a\x0a /X\h*\R/BZ ------------------------------------------------------------------ Bra X \h*+ \R Ket End ------------------------------------------------------------------ X\x20\x0a 0: X \x0a /X\H*\R/BZ ------------------------------------------------------------------ Bra X \H* \R Ket End ------------------------------------------------------------------ X\x0d\x0a 0: X\x0d\x0a /X\H+\R/BZ ------------------------------------------------------------------ Bra X \H+ \R Ket End ------------------------------------------------------------------ X\x0d\x0a 0: X\x0d\x0a /X\H++\R/BZ ------------------------------------------------------------------ Bra X \H++ \R Ket End ------------------------------------------------------------------ X\x0d\x0a No match /-- Perl treats this one differently, not failing the second string. I believe that is a bug in Perl. --/ /^((abc|abcx)(*THEN)y|abcd)/ abcd 0: abcd 1: abcd *** Failers No match abcxy No match /(?<=abc)def/ abc\P\P Partial match: abc /abc$/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc$/m abc 0: abc abc\n 0: abc abc\P\P Partial match: abc abc\n\P\P 0: abc abc\P 0: abc abc\n\P 0: abc /abc\z/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc\Z/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc\b/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc\B/ abc No match abc\P Partial match: abc abc\P\P Partial match: abc /.+/ abc\>0 0: abc abc\>1 0: bc abc\>2 0: c abc\>3 No match abc\>4 Error -24 (bad offset value) abc\>-4 Error -24 (bad offset value) /^\cÄ£/ Failed: \c must be followed by an ASCII character at offset 3 /(?P(?P=abn)xxx)/BZ ------------------------------------------------------------------ Bra Once CBra 1 \1 xxx Ket Ket Ket End ------------------------------------------------------------------ /(a\1z)/BZ ------------------------------------------------------------------ Bra Once CBra 1 a \1 z Ket Ket Ket End ------------------------------------------------------------------ /(?P(?P=abn)(?(?P=axn)xxx)/BZ Failed: reference to non-existent subpattern at offset 15 /(?P(?P=axn)xxx)(?yy)/BZ ------------------------------------------------------------------ Bra CBra 1 \2 xxx Ket CBra 2 yy Ket Ket End ------------------------------------------------------------------ /-- These tests are here because Perl gets the first one wrong. --/ /(\R*)(.)/s \r\n 0: \x0d 1: 2: \x0d \r\r\n\n\r 0: \x0d\x0d\x0a\x0a\x0d 1: \x0d\x0d\x0a\x0a 2: \x0d \r\r\n\n\r\n 0: \x0d\x0d\x0a\x0a\x0d 1: \x0d\x0d\x0a\x0a 2: \x0d /(\R)*(.)/s \r\n 0: \x0d 1: 2: \x0d \r\r\n\n\r 0: \x0d\x0d\x0a\x0a\x0d 1: \x0a 2: \x0d \r\r\n\n\r\n 0: \x0d\x0d\x0a\x0a\x0d 1: \x0a 2: \x0d /((?>\r\n|\n|\x0b|\f|\r|\x85)*)(.)/s \r\n 0: \x0d 1: 2: \x0d \r\r\n\n\r 0: \x0d\x0d\x0a\x0a\x0d 1: \x0d\x0d\x0a\x0a 2: \x0d \r\r\n\n\r\n 0: \x0d\x0d\x0a\x0a\x0d 1: \x0d\x0d\x0a\x0a 2: \x0d /-- --/ /^abc$/BZ ------------------------------------------------------------------ Bra ^ abc $ Ket End ------------------------------------------------------------------ /^abc$/BZm ------------------------------------------------------------------ Bra /m ^ abc /m $ Ket End ------------------------------------------------------------------ /^(a)*+(\w)/S aaaaX 0: aaaaX 1: a 2: X ** Failers No match aaaa No match /^(?:a)*+(\w)/S aaaaX 0: aaaaX 1: X ** Failers No match aaaa No match /(a)++1234/SDZ ------------------------------------------------------------------ Bra CBraPos 1 a KetRpos 1234 Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 No options First char = 'a' Need char = '4' Subject length lower bound = 5 No set of starting bytes /([abc])++1234/SI Capturing subpattern count = 1 No options No first char Need char = '4' Subject length lower bound = 5 Starting byte set: a b c /(?<=(abc)+)X/ Failed: lookbehind assertion is not fixed length at offset 10 /(^ab)/I Capturing subpattern count = 1 Options: anchored No first char No need char /(^ab)++/I Capturing subpattern count = 1 Options: anchored No first char No need char /(^ab|^)+/I Capturing subpattern count = 1 Options: anchored No first char No need char /(^ab|^)++/I Capturing subpattern count = 1 Options: anchored No first char No need char /(?:^ab)/I Capturing subpattern count = 0 Options: anchored No first char No need char /(?:^ab)++/I Capturing subpattern count = 0 Options: anchored No first char No need char /(?:^ab|^)+/I Capturing subpattern count = 0 Options: anchored No first char No need char /(?:^ab|^)++/I Capturing subpattern count = 0 Options: anchored No first char No need char /(.*ab)/I Capturing subpattern count = 1 No options First char at start or follows newline Need char = 'b' /(.*ab)++/I Capturing subpattern count = 1 No options First char at start or follows newline Need char = 'b' /(.*ab|.*)+/I Capturing subpattern count = 1 No options First char at start or follows newline No need char /(.*ab|.*)++/I Capturing subpattern count = 1 No options First char at start or follows newline No need char /(?:.*ab)/I Capturing subpattern count = 0 No options First char at start or follows newline Need char = 'b' /(?:.*ab)++/I Capturing subpattern count = 0 No options First char at start or follows newline Need char = 'b' /(?:.*ab|.*)+/I Capturing subpattern count = 0 No options First char at start or follows newline No need char /(?:.*ab|.*)++/I Capturing subpattern count = 0 No options First char at start or follows newline No need char /(?=a)[bcd]/I Capturing subpattern count = 0 No options First char = 'a' No need char /((?=a))[bcd]/I Capturing subpattern count = 1 No options First char = 'a' No need char /((?=a))+[bcd]/I Capturing subpattern count = 1 No options First char = 'a' No need char /((?=a))++[bcd]/I Capturing subpattern count = 1 No options First char = 'a' No need char /(?=a+)[bcd]/iI Capturing subpattern count = 0 Options: caseless First char = 'a' (caseless) No need char /(?=a+?)[bcd]/iI Capturing subpattern count = 0 Options: caseless First char = 'a' (caseless) No need char /(?=a++)[bcd]/iI Capturing subpattern count = 0 Options: caseless First char = 'a' (caseless) No need char /(?=a{3})[bcd]/iI Capturing subpattern count = 0 Options: caseless First char = 'a' (caseless) Need char = 'a' (caseless) /(abc)\1+/S /-- Perl doesn't get these right IMO (the 3rd is PCRE-specific) --/ /(?1)(?:(b(*ACCEPT))){0}/ b 0: b /(?1)(?:(b(*ACCEPT))){0}c/ bc 0: bc ** Failers No match b No match /(?1)(?:((*ACCEPT))){0}c/ c 0: c c\N 0: c /^.*?(?(?=a)a|b(*THEN)c)/ ba No match /^.*?(?(?=a)a|bc)/ ba 0: ba /^.*?(?(?=a)a(*THEN)b|c)/ ac No match /^.*?(?(?=a)a(*THEN)b)c/ ac No match /^.*?(a(*THEN)b)c/ aabc No match /^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x aabc 0: aabc /^.*?(a(*THEN)b|z)c/ aabc 0: aabc 1: ab /^.*?(z|a(*THEN)b)c/ aabc 0: aabc 1: ab /-- --/ /-- These studied versions are here because they are not Perl-compatible; the studying means the mark is not seen. --/ /(*MARK:A)(*SKIP:B)(C|X)/KS C 0: C 1: C MK: A D No match, mark = A /(*:A)A+(*SKIP:A)(B|Z)/KS AAAC No match, mark = A /-- --/ "(?=a*(*ACCEPT)b)c" c 0: c c\N 0: c /(?1)c(?(DEFINE)((*ACCEPT)b))/ c 0: c c\N 0: c /(?>(*ACCEPT)b)c/ c 0: c\N No match /(?:(?>(a)))+a%/++ %aa% 0: aa% 0+ 1: a 1+ a% /(a)b|ac/++SS ac\O3 Matched, but too many substrings 0: ac 0+ /(a)(b)x|abc/++ abc\O6 0: abc 0+ /(a)bc|(a)(b)\2/ \O3abc Matched, but too many substrings 0: abc \O4abc Matched, but too many substrings 0: abc /(?(DEFINE)(a(?2)|b)(b(?1)|a))(?:(?1)|(?2))/SI Capturing subpattern count = 2 No options No first char No need char Subject length lower bound = 1 No set of starting bytes /(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI Capturing subpattern count = 2 No options No first char No need char Subject length lower bound = 3 Starting byte set: a b /(a(?2)|b)(b(?1)|a)(?1)(?2)/SI Capturing subpattern count = 2 No options No first char No need char Subject length lower bound = 4 Starting byte set: a b /(abc)(?1)/SI Capturing subpattern count = 1 No options First char = 'a' Need char = 'c' Subject length lower bound = 6 No set of starting bytes /^(?>a)++/ aa\M Minimum match() limit = 5 Minimum match() recursion limit = 2 0: aa aaaaaaaaa\M Minimum match() limit = 12 Minimum match() recursion limit = 2 0: aaaaaaaaa /(a)(?1)++/ aa\M Minimum match() limit = 7 Minimum match() recursion limit = 4 0: aa 1: a aaaaaaaaa\M Minimum match() limit = 21 Minimum match() recursion limit = 4 0: aaaaaaaaa 1: a /(?:(foo)|(bar)|(baz))X/SS= bazfooX 0: fooX 1: foo 2: 3: foobazbarX 0: barX 1: 2: bar 3: barfooX 0: fooX 1: foo 2: 3: bazX 0: bazX 1: 2: 3: baz foobarbazX 0: bazX 1: 2: 3: baz bazfooX\O0 Matched, but too many substrings bazfooX\O2 Matched, but too many substrings 0: fooX bazfooX\O4 Matched, but too many substrings 0: fooX 1: bazfooX\O6 Matched, but too many substrings 0: fooX 1: foo 2: bazfooX\O8 Matched, but too many substrings 0: fooX 1: foo 2: 3: bazfooX\O10 0: fooX 1: foo 2: 3: /(?=abc){3}abc/BZ ------------------------------------------------------------------ Bra Assert abc Ket abc Ket End ------------------------------------------------------------------ /(?=abc)+abc/BZ ------------------------------------------------------------------ Bra Assert abc Ket abc Ket End ------------------------------------------------------------------ /(?=abc)++abc/BZ ------------------------------------------------------------------ Bra Assert abc Ket abc Ket End ------------------------------------------------------------------ /(?=abc){0}xyz/BZ ------------------------------------------------------------------ Bra Skip zero Assert abc Ket xyz Ket End ------------------------------------------------------------------ /(?=(a))?./BZ ------------------------------------------------------------------ Bra Brazero Assert CBra 1 a Ket Ket Any Ket End ------------------------------------------------------------------ /(?=(a))??./BZ ------------------------------------------------------------------ Bra Braminzero Assert CBra 1 a Ket Ket Any Ket End ------------------------------------------------------------------ /^(?=(a)){0}b(?1)/BZ ------------------------------------------------------------------ Bra ^ Skip zero Assert CBra 1 a Ket Ket b Recurse Ket End ------------------------------------------------------------------ /(?(DEFINE)(a))?b(?1)/BZ ------------------------------------------------------------------ Bra Cond Cond def CBra 1 a Ket Ket b Recurse Ket End ------------------------------------------------------------------ /^(?=(?1))?[az]([abc])d/BZ ------------------------------------------------------------------ Bra ^ Brazero Assert Recurse Ket [az] CBra 1 [a-c] Ket d Ket End ------------------------------------------------------------------ /^(?!a){0}\w+/BZ ------------------------------------------------------------------ Bra ^ Skip zero Assert not a Ket \w+ Ket End ------------------------------------------------------------------ /(?<=(abc))?xyz/BZ ------------------------------------------------------------------ Bra Brazero AssertB Reverse CBra 1 abc Ket Ket xyz Ket End ------------------------------------------------------------------ /[:a[:abc]b:]/BZ ------------------------------------------------------------------ Bra [:[a-c] b:] Ket End ------------------------------------------------------------------ /((?2))((?1))/SS abc Error -26 (nested recursion at the same subject position) /((?(R2)a+|(?1)b))/SS aaaabcde Error -26 (nested recursion at the same subject position) /(?(R)a*(?1)|((?R))b)/SS aaaabcde Error -26 (nested recursion at the same subject position) /(a+|(?R)b)/ Failed: recursive call could loop indefinitely at offset 7 /^(a(*:A)(d|e(*:B))z|aeq)/C adz --->adz +0 ^ ^ +1 ^ (a(*:A)(d|e(*:B))z|aeq) +2 ^ a +3 ^^ (*:A) +8 ^^ (d|e(*:B)) Latest Mark: A +9 ^^ d +10 ^ ^ | +18 ^ ^ z +19 ^ ^ | +24 ^ ^ 0: adz 1: adz 2: d aez --->aez +0 ^ ^ +1 ^ (a(*:A)(d|e(*:B))z|aeq) +2 ^ a +3 ^^ (*:A) +8 ^^ (d|e(*:B)) Latest Mark: A +9 ^^ d +11 ^^ e +12 ^ ^ (*:B) +17 ^ ^ ) Latest Mark: B +18 ^ ^ z +19 ^ ^ | +24 ^ ^ 0: aez 1: aez 2: e aeqwerty --->aeqwerty +0 ^ ^ +1 ^ (a(*:A)(d|e(*:B))z|aeq) +2 ^ a +3 ^^ (*:A) +8 ^^ (d|e(*:B)) Latest Mark: A +9 ^^ d +11 ^^ e +12 ^ ^ (*:B) +17 ^ ^ ) Latest Mark: B +18 ^ ^ z +20 ^ a +21 ^^ e +22 ^ ^ q +23 ^ ^ ) +24 ^ ^ 0: aeq 1: aeq /.(*F)/ \P\Pabc No match /\btype\b\W*?\btext\b\W*?\bjavascript\b/IS Capturing subpattern count = 0 No options First char = 't' Need char = 't' Max lookbehind = 1 Subject length lower bound = 18 No set of starting bytes /\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|a+)(?>(z+))\w/BZ ------------------------------------------------------------------ Bra ^ Once_NC a+ Ket Once CBra 1 z+ Ket Ket \w Ket End ------------------------------------------------------------------ aaaazzzzb 0: aaaazzzzb 1: zzzz ** Failers No match aazz No match /(.)(\1|a(?2))/ bab 0: bab 1: b 2: ab /\1|(.)(?R)\1/ cbbbc 0: cbbbc 1: c /(.)((?(1)c|a)|a(?2))/ baa No match /(?P(?P=abn)xxx)/BZ ------------------------------------------------------------------ Bra Once CBra 1 \1 xxx Ket Ket Ket End ------------------------------------------------------------------ /(a\1z)/BZ ------------------------------------------------------------------ Bra Once CBra 1 a \1 z Ket Ket Ket End ------------------------------------------------------------------ /^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ \Maabbccddee Minimum match() limit = 12 Minimum match() recursion limit = 3 0: aabbccddee /^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ \Maabbccddee Minimum match() limit = 22 Minimum match() recursion limit = 21 0: aabbccddee 1: aa 2: bb 3: cc 4: dd 5: ee /^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ \Maabbccddee Minimum match() limit = 18 Minimum match() recursion limit = 13 0: aabbccddee 1: aa 2: cc 3: ee /^a\x41z/ aAz 0: aAz *** Failers No match ax41z No match /^a[m\x41]z/ aAz 0: aAz /^a\x1z/ ax1z 0: ax1z /^a\u0041z/ aAz 0: aAz *** Failers No match au0041z No match /^a[m\u0041]z/ aAz 0: aAz /^a\u041z/ au041z 0: au041z *** Failers No match aAz No match /^a\U0041z/ aU0041z 0: aU0041z *** Failers No match aAz No match /(?(?=c)c|d)++Y/BZ ------------------------------------------------------------------ Bra BraPos Cond Assert c Ket c Alt d Ket KetRpos Y Ket End ------------------------------------------------------------------ /(?(?=c)c|d)*+Y/BZ ------------------------------------------------------------------ Bra Braposzero BraPos Cond Assert c Ket c Alt d Ket KetRpos Y Ket End ------------------------------------------------------------------ /a[\NB]c/ Failed: \N is not supported in a class at offset 3 /a[B-\Nc]/ Failed: \N is not supported in a class at offset 5 /(a)(?2){0,1999}?(b)/ /(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/ /--- This test, with something more complicated than individual letters, causes different behaviour in Perl. Perhaps it disables some optimization; no tag is passed back for the failures, whereas in PCRE there is a tag. ---/ /(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK AABC 0: AB 1: A 2: B MK: A XXYZ 0: XXY 1: 2: 3: X 4: X 5: Y MK: B ** Failers No match XAQQ No match, mark = A XAQQXZZ No match, mark = A AXQQQ No match, mark = A AXXQQQ No match, mark = B /-- Perl doesn't give marks for these, though it does if the alternatives are replaced by single letters. --/ /(b|q)(*:m)f|a(*:n)w/K aw 0: aw MK: n ** Failers No match, mark = n abc No match, mark = m /(q|b)(*:m)f|a(*:n)w/K aw 0: aw MK: n ** Failers No match, mark = n abc No match, mark = m /-- After a partial match, the behaviour is as for a failure. --/ /^a(*:X)bcde/K abc\P Partial match, mark=X: abc /-- These are here because Perl doesn't return a mark, except for the first --/ /(?=(*:x))(q|)/K+ abc 0: 0+ abc 1: MK: x /(?=(*:x))((*:y)q|)/K+ abc 0: 0+ abc 1: MK: x /(?=(*:x))(?:(*:y)q|)/K+ abc 0: 0+ abc MK: x /(?=(*:x))(?>(*:y)q|)/K+ abc 0: 0+ abc MK: x /(?=a(*:x))(?!a(*:y)c)/K+ ab 0: 0+ ab MK: x /(?=a(*:x))(?=a(*:y)c|)/K+ ab 0: 0+ ab MK: x /(..)\1/ ab\P Partial match: ab aba\P Partial match: aba abab\P 0: abab 1: ab /(..)\1/i ab\P Partial match: ab abA\P Partial match: abA aBAb\P 0: aBAb 1: aB /(..)\1{2,}/ ab\P Partial match: ab aba\P Partial match: aba abab\P Partial match: abab ababa\P Partial match: ababa ababab\P 0: ababab 1: ab ababab\P\P Partial match: ababab abababa\P 0: ababab 1: ab abababa\P\P Partial match: abababa /(..)\1{2,}/i ab\P Partial match: ab aBa\P Partial match: aBa aBAb\P Partial match: aBAb AbaBA\P Partial match: AbaBA abABAb\P 0: abABAb 1: ab aBAbaB\P\P Partial match: aBAbaB abABabA\P 0: abABab 1: ab abaBABa\P\P Partial match: abaBABa /(..)\1{2,}?x/i ab\P Partial match: ab abA\P Partial match: abA aBAb\P Partial match: aBAb abaBA\P Partial match: abaBA abAbaB\P Partial match: abAbaB abaBabA\P Partial match: abaBabA abAbABaBx\P 0: abAbABaBx 1: ab /^(..)\1/ aba\P Partial match: aba /^(..)\1{2,3}x/ aba\P Partial match: aba ababa\P Partial match: ababa ababa\P\P Partial match: ababa abababx 0: abababx 1: ab ababababx 0: ababababx 1: ab /^(..)\1{2,3}?x/ aba\P Partial match: aba ababa\P Partial match: ababa ababa\P\P Partial match: ababa abababx 0: abababx 1: ab ababababx 0: ababababx 1: ab /^(..)(\1{2,3})ab/ abababab 0: abababab 1: ab 2: abab /^\R/ \r\P 0: \x0d \r\P\P Partial match: \x0d /^\R{2,3}x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P Partial match: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P Partial match: \x0d\x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d \r\rx 0: \x0d\x0dx \r\r\rx 0: \x0d\x0d\x0dx /^\R{2,3}?x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P Partial match: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P Partial match: \x0d\x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d \r\rx 0: \x0d\x0dx \r\r\rx 0: \x0d\x0d\x0dx /^\R?x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d x 0: x \rx 0: \x0dx /^\R+x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\n\P Partial match: \x0d\x0a \r\n\P\P Partial match: \x0d\x0a \rx 0: \x0dx /^a$/ a\r\P Partial match: a\x0d a\r\P\P Partial match: a\x0d /^a$/m a\r\P Partial match: a\x0d a\r\P\P Partial match: a\x0d /^(a$|a\r)/ a\r\P 0: a\x0d 1: a\x0d a\r\P\P Partial match: a\x0d /^(a$|a\r)/m a\r\P 0: a\x0d 1: a\x0d a\r\P\P Partial match: a\x0d /./ \r\P 0: \x0d \r\P\P Partial match: \x0d /.{2,3}/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P 0: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P 0: \x0d\x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d /.{2,3}?/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P 0: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P 0: \x0d\x0d \r\r\r\P\P 0: \x0d\x0d /-- These two are here because Perl does not match: it seems to allow the COMMIT to escape from the assertion. --/ /(?=a(*COMMIT)b|ac)ac|ac/ ac 0: ac /(?=a(*COMMIT)b|(ac)) ac | (a)c/x ac 0: ac 1: 2: a "AB(C(D))(E(F))?(?(?=\2)(?=\4))" ABCDGHI\O03 Matched, but too many substrings 0: ABCD /-- This one is here because Perl does not confine the *COMMIT to the assertion, and therefore fails the entire subroutine call. --/ /((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ ac 0: ac /-- End of testinput2 --/ pcre-8.31/testdata/testoutput30000644000222100022210000000500111257432623013363 00000000000000/-- This set of tests checks local-specific features, using the fr_FR locale. It is not Perl-compatible. There is different version called wintestinput3 f or use on Windows, where the locale is called "french". --/ /^[\w]+/ *** Failers No match École No match /^[\w]+/Lfr_FR École 0: École /^[\w]+/ *** Failers No match École No match /^[\W]+/ École 0: \xc9 /^[\W]+/Lfr_FR *** Failers 0: *** École No match /[\b]/ \b 0: \x08 *** Failers No match a No match /[\b]/Lfr_FR \b 0: \x08 *** Failers No match a No match /^\w+/ *** Failers No match École No match /^\w+/Lfr_FR École 0: École /(.+)\b(.+)/ École 0: \xc9cole 1: \xc9 2: cole /(.+)\b(.+)/Lfr_FR *** Failers 0: *** Failers 1: *** 2: Failers École No match /École/i École 0: \xc9cole *** Failers No match école No match /École/iLfr_FR École 0: École école 0: école /\w/IS Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z /\w/ISLfr_FR Capturing subpattern count = 0 No options No first char No need char Subject length lower bound = 1 Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ /^[\xc8-\xc9]/iLfr_FR École 0: É école 0: é /^[\xc8-\xc9]/Lfr_FR École 0: É *** Failers No match école No match /\W+/Lfr_FR >>>\xaa<<< 0: >>> >>>\xba<<< 0: >>> /[\W]+/Lfr_FR >>>\xaa<<< 0: >>> >>>\xba<<< 0: >>> /[^[:alpha:]]+/Lfr_FR >>>\xaa<<< 0: >>> >>>\xba<<< 0: >>> /\w+/Lfr_FR >>>\xaa<<< 0: ª >>>\xba<<< 0: º /[\w]+/Lfr_FR >>>\xaa<<< 0: ª >>>\xba<<< 0: º /[[:alpha:]]+/Lfr_FR >>>\xaa<<< 0: ª >>>\xba<<< 0: º /[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR ------------------------------------------------------------------ Bra [A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff] [a-z\xb5\xdf-\xf6\xf8-\xff] [A-Z\xc0-\xd6\xd8-\xde] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /-- End of testinput3 --/ pcre-8.31/testdata/testoutput40000644000222100022210000005051511676645221013403 00000000000000/-- This set of tests is for UTF support, excluding Unicode properties. It is compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit PCRE libraries. --/ /a.b/8 acb 0: acb a\x7fb 0: a\x{7f}b a\x{100}b 0: a\x{100}b *** Failers No match a\nb No match /a(.{3})b/8 a\x{4000}xyb 0: a\x{4000}xyb 1: \x{4000}xy a\x{4000}\x7fyb 0: a\x{4000}\x{7f}yb 1: \x{4000}\x{7f}y a\x{4000}\x{100}yb 0: a\x{4000}\x{100}yb 1: \x{4000}\x{100}y *** Failers No match a\x{4000}b No match ac\ncb No match /a(.*?)(.)/ a\xc0\x88b 0: a\xc0 1: 2: \xc0 /a(.*?)(.)/8 a\x{100}b 0: a\x{100} 1: 2: \x{100} /a(.*)(.)/ a\xc0\x88b 0: a\xc0\x88b 1: \xc0\x88 2: b /a(.*)(.)/8 a\x{100}b 0: a\x{100}b 1: \x{100} 2: b /a(.)(.)/ a\xc0\x92bcd 0: a\xc0\x92 1: \xc0 2: \x92 /a(.)(.)/8 a\x{240}bcd 0: a\x{240}b 1: \x{240} 2: b /a(.?)(.)/ a\xc0\x92bcd 0: a\xc0\x92 1: \xc0 2: \x92 /a(.?)(.)/8 a\x{240}bcd 0: a\x{240}b 1: \x{240} 2: b /a(.??)(.)/ a\xc0\x92bcd 0: a\xc0 1: 2: \xc0 /a(.??)(.)/8 a\x{240}bcd 0: a\x{240} 1: 2: \x{240} /a(.{3})b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} *** Failers No match a\x{1234}b No match ac\ncb No match /a(.{3,})b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxbcdefghijb 1: xxxxbcdefghij a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} *** Failers No match a\x{1234}b No match /a(.{3,}?)b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxb 1: xxxx a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} *** Failers No match a\x{1234}b No match /a(.{3,5})b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxb 1: xxxx a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} axbxxbcdefghijb 0: axbxxb 1: xbxx axxxxxbcdefghijb 0: axxxxxb 1: xxxxx *** Failers No match a\x{1234}b No match axxxxxxbcdefghijb No match /a(.{3,5}?)b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxb 1: xxxx a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} axbxxbcdefghijb 0: axbxxb 1: xbxx axxxxxbcdefghijb 0: axxxxxb 1: xxxxx *** Failers No match a\x{1234}b No match axxxxxxbcdefghijb No match /^[a\x{c0}]/8 *** Failers No match \x{100} No match /(?<=aXb)cd/8 aXbcd 0: cd /(?<=a\x{100}b)cd/8 a\x{100}bcd 0: cd /(?<=a\x{100000}b)cd/8 a\x{100000}bcd 0: cd /(?:\x{100}){3}b/8 \x{100}\x{100}\x{100}b 0: \x{100}\x{100}\x{100}b *** Failers No match \x{100}\x{100}b No match /\x{ab}/8 \x{ab} 0: \x{ab} \xc2\xab 0: \x{ab} *** Failers No match \x00{ab} No match /(?<=(.))X/8 WXYZ 0: X 1: W \x{256}XYZ 0: X 1: \x{256} *** Failers No match XYZ No match /[^a]+/8g bcd 0: bcd \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z /^[^a]{2}/8 \x{100}bc 0: \x{100}b /^[^a]{2,}/8 \x{100}bcAa 0: \x{100}bcA /^[^a]{2,}?/8 \x{100}bca 0: \x{100}b /[^a]+/8ig bcd 0: bcd \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z /^[^a]{2}/8i \x{100}bc 0: \x{100}b /^[^a]{2,}/8i \x{100}bcAa 0: \x{100}bc /^[^a]{2,}?/8i \x{100}bca 0: \x{100}b /\x{100}{0,0}/8 abcd 0: /\x{100}?/8 abcd 0: \x{100}\x{100} 0: \x{100} /\x{100}{0,3}/8 \x{100}\x{100} 0: \x{100}\x{100} \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} /\x{100}*/8 abce 0: \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} /\x{100}{1,1}/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100} /\x{100}{1,3}/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} /\x{100}+/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} /\x{100}{3}/8 abcd\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100} /\x{100}{3,5}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100} /\x{100}{3,}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /(?<=a\x{100}{2}b)X/8+ Xyyya\x{100}\x{100}bXzzz 0: X 0+ zzz /\D*/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /\D*/8 \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /\D/8 1X2 0: X 1\x{100}2 0: \x{100} />\S/8 > >X Y 0: >X > >\x{100} Y 0: >\x{100} /\d/8 \x{100}3 0: 3 /\s/8 \x{100} X 0: /\D+/8 12abcd34 0: abcd *** Failers 0: *** Failers 1234 No match /\D{2,3}/8 12abcd34 0: abc 12ab34 0: ab *** Failers 0: *** 1234 No match 12a34 No match /\D{2,3}?/8 12abcd34 0: ab 12ab34 0: ab *** Failers 0: ** 1234 No match 12a34 No match /\d+/8 12abcd34 0: 12 *** Failers No match /\d{2,3}/8 12abcd34 0: 12 1234abcd 0: 123 *** Failers No match 1.4 No match /\d{2,3}?/8 12abcd34 0: 12 1234abcd 0: 12 *** Failers No match 1.4 No match /\S+/8 12abcd34 0: 12abcd34 *** Failers 0: *** \ \ No match /\S{2,3}/8 12abcd34 0: 12a 1234abcd 0: 123 *** Failers 0: *** \ \ No match /\S{2,3}?/8 12abcd34 0: 12 1234abcd 0: 12 *** Failers 0: ** \ \ No match />\s+ <34 0: > < 0+ 34 *** Failers No match />\s{2,3} < 0+ cd ab> < 0+ ce *** Failers No match ab> \s{2,3}? < 0+ cd ab> < 0+ ce *** Failers No match ab> \xff< 0: \xff /[\xff]/8 >\x{ff}< 0: \x{ff} /[^\xFF]/ XYZ 0: X /[^\xff]/8 XYZ 0: X \x{123} 0: \x{123} /^[ac]*b/8 xb No match /^[ac\x{100}]*b/8 xb No match /^[^x]*b/8i xb No match /^[^x]*b/8 xb No match /^\d*b/8 xb No match /(|a)/g8 catac 0: 1: 0: 1: 0: a 1: a 0: 1: 0: 1: 0: a 1: a 0: 1: 0: 1: a\x{256}a 0: 1: 0: a 1: a 0: 1: 0: 1: 0: a 1: a 0: 1: /^\x{85}$/8i \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 /a*\x{100}*\w/8 a 0: a /\S\S/8g A\x{a3}BC 0: A\x{a3} 0: BC /\S{2}/8g A\x{a3}BC 0: A\x{a3} 0: BC /\W\W/8g +\x{a3}== 0: +\x{a3} 0: == /\W{2}/8g +\x{a3}== 0: +\x{a3} 0: == /\S/8g \x{442}\x{435}\x{441}\x{442} 0: \x{442} 0: \x{435} 0: \x{441} 0: \x{442} /[\S]/8g \x{442}\x{435}\x{441}\x{442} 0: \x{442} 0: \x{435} 0: \x{441} 0: \x{442} /\D/8g \x{442}\x{435}\x{441}\x{442} 0: \x{442} 0: \x{435} 0: \x{441} 0: \x{442} /[\D]/8g \x{442}\x{435}\x{441}\x{442} 0: \x{442} 0: \x{435} 0: \x{441} 0: \x{442} /\W/8g \x{2442}\x{2435}\x{2441}\x{2442} 0: \x{2442} 0: \x{2435} 0: \x{2441} 0: \x{2442} /[\W]/8g \x{2442}\x{2435}\x{2441}\x{2442} 0: \x{2442} 0: \x{2435} 0: \x{2441} 0: \x{2442} /[\S\s]*/8 abc\n\r\x{442}\x{435}\x{441}\x{442}xyz 0: abc\x{0a}\x{0d}\x{442}\x{435}\x{441}\x{442}xyz /[\x{41f}\S]/8g \x{442}\x{435}\x{441}\x{442} 0: \x{442} 0: \x{435} 0: \x{441} 0: \x{442} /.[^\S]./8g abc def\x{442}\x{443}xyz\npqr 0: c d 0: z\x{0a}p /.[^\S\n]./8g abc def\x{442}\x{443}xyz\npqr 0: c d /[[:^alnum:]]/8g +\x{2442} 0: + 0: \x{2442} /[[:^alpha:]]/8g +\x{2442} 0: + 0: \x{2442} /[[:^ascii:]]/8g A\x{442} 0: \x{442} /[[:^blank:]]/8g A\x{442} 0: A 0: \x{442} /[[:^cntrl:]]/8g A\x{442} 0: A 0: \x{442} /[[:^digit:]]/8g A\x{442} 0: A 0: \x{442} /[[:^graph:]]/8g \x19\x{e01ff} 0: \x{19} 0: \x{e01ff} /[[:^lower:]]/8g A\x{422} 0: A 0: \x{422} /[[:^print:]]/8g \x{19}\x{e01ff} 0: \x{19} 0: \x{e01ff} /[[:^punct:]]/8g A\x{442} 0: A 0: \x{442} /[[:^space:]]/8g A\x{442} 0: A 0: \x{442} /[[:^upper:]]/8g a\x{442} 0: a 0: \x{442} /[[:^word:]]/8g +\x{2442} 0: + 0: \x{2442} /[[:^xdigit:]]/8g M\x{442} 0: M 0: \x{442} /[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞĀĂĄĆĈĊČĎÄĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿÅŃŅŇŊŌŎÅÅ’Å”Å–Å˜ÅšÅœÅžÅ Å¢Å¤Å¦Å¨ÅªÅ¬Å®Å°Å²Å´Å¶Å¸Å¹Å»Å½ÆÆ‚Æ„Æ†Æ‡Æ‰ÆŠÆ‹ÆŽÆÆÆ‘Æ“Æ”Æ–Æ—Æ˜ÆœÆÆŸÆ Æ¢Æ¤Æ¦Æ§Æ©Æ¬Æ®Æ¯Æ±Æ²Æ³ÆµÆ·Æ¸Æ¼Ç„LJNJÇÇǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎÈȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾÉΆΈΉΊΌΎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀÐЂЃЄЅІЇЈЉЊЋЌÐÐŽÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎÒҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀÓÓƒÓ…Ó‡Ó‰Ó‹ÓÓӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀÕÕ‚ÕƒÕ„Õ…Õ†Õ‡ÕˆÕ‰ÕŠÕ‹ÕŒÕÕŽÕÕՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀáƒáƒ‚ჃჄჅḀḂḄḆḈḊḌḎá¸á¸’ḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎá¹á¹’ṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎáºáº’ẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎá»á»’ỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌá¼á¼Žá¼á¼˜á¼™á¼šá¼›á¼œá¼á¼¨á¼©á¼ªá¼«á¼¬á¼­á¼®á¼¯á¼¸á¼¹á¼ºá¼»á¼¼á¼½á¼¾á¼¿á½ˆá½‰á½Šá½‹á½Œá½á½™á½›á½á½Ÿá½¨á½©á½ªá½«á½¬á½­á½®á½¯á¾¸á¾¹á¾ºá¾»á¿ˆá¿‰á¿Šá¿‹á¿˜á¿™á¿šá¿›á¿¨á¿©á¿ªá¿«á¿¬á¿¸á¿¹á¿ºá¿»abcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿÄăąćĉċÄÄđēĕėęěÄğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋÅÅőœŕŗřśÅÅŸÅ¡Å£Å¥Å§Å©Å«Å­Å¯Å±Å³ÅµÅ·ÅºÅ¼Å¾Å¿Æ€ÆƒÆ…ÆˆÆŒÆÆ’ƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎÇǒǔǖǘǚǜÇǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿÈȃȅȇȉȋÈÈȑȓȕȗșțÈȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀÉɑɒɓɔɕɖɗɘəɚɛɜÉɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀÊʂʃʄʅʆʇʈʉʊʋʌÊÊŽÊÊʑʒʓʔʕʖʗʘʙʚʛʜÊʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯÎάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏÏŽÏϑϕϖϗϙϛÏϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑёђѓєѕіїјљњћќÑўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿÒÒ‹ÒÒÒ‘Ò“Ò•Ò—Ò™Ò›ÒҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛÓÓŸÓ¡Ó£Ó¥Ó§Ó©Ó«Ó­Ó¯Ó±Ó³ÓµÓ·Ó¹ÔÔƒÔ…Ô‡Ô‰Ô‹ÔÔÕ¡Õ¢Õ£Õ¤Õ¥Õ¦Õ§Õ¨Õ©ÕªÕ«Õ¬Õ­Õ®Õ¯Õ°Õ±Õ²Õ³Õ´ÕµÕ¶Õ·Õ¸Õ¹ÕºÕ»Õ¼Õ½Õ¾Õ¿Ö€Öւփքօֆևᴀá´á´‚ᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌá´á´Žá´á´á´‘ᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜá´á´žá´Ÿá´ á´¡á´¢á´£á´¤á´¥á´¦á´§á´¨á´©á´ªá´«áµ¢áµ£áµ¤áµ¥áµ¦áµ§áµ¨áµ©áµªáµ«áµ¬áµ­áµ®áµ¯áµ°áµ±áµ²áµ³áµ´áµµáµ¶áµ·áµ¹áµºáµ»áµ¼áµ½áµ¾áµ¿á¶€á¶á¶‚ᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌá¶á¶Žá¶á¶á¶‘ᶒᶓᶔᶕᶖᶗᶘᶙᶚá¸á¸ƒá¸…ḇḉḋá¸á¸á¸‘ḓḕḗḙḛá¸á¸Ÿá¸¡á¸£á¸¥á¸§á¸©á¸«á¸­á¸¯á¸±á¸³á¸µá¸·á¸¹á¸»á¸½á¸¿á¹á¹ƒá¹…ṇṉṋá¹á¹á¹‘ṓṕṗṙṛá¹á¹Ÿá¹¡á¹£á¹¥á¹§á¹©á¹«á¹­á¹¯á¹±á¹³á¹µá¹·á¹¹á¹»á¹½á¹¿áºáºƒáº…ẇẉẋáºáºáº‘ẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếá»á»ƒá»…ệỉịá»á»á»‘ồổỗộớá»á»Ÿá»¡á»£á»¥á»§á»©á»«á»­á»¯á»±á»³á»µá»·á»¹á¼€á¼á¼‚ἃἄἅἆἇá¼á¼‘ἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀá½á½‚ὃὄὅá½á½‘ὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀá¾á¾‚ᾃᾄᾅᾆᾇá¾á¾‘ᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇá¿á¿‘ῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷâ²â²ƒâ²…ⲇⲉⲋâ²â²â²‘ⲓⲕⲗⲙⲛâ²â²Ÿâ²¡â²£â²¥â²§â²©â²«â²­â²¯â²±â²³â²µâ²·â²¹â²»â²½â²¿â³â³ƒâ³…ⳇⳉⳋâ³â³â³‘ⳓⳕⳗⳙⳛâ³â³Ÿâ³¡â³£â³¤â´€â´â´‚ⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌâ´â´Žâ´â´â´‘ⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜâ´â´žâ´Ÿâ´ â´¡â´¢â´£â´¤â´¥ï¬€ï¬ï¬‚ffifflſtstﬓﬔﬕﬖﬗ\d-_^]/8 /^[^d]*?$/ abc 0: abc /^[^d]*?$/8 abc 0: abc /^[^d]*?$/i abc 0: abc /^[^d]*?$/8i abc 0: abc /(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]/8 /^[a\x{c0}]b/8 \x{c0}b 0: \x{c0}b /^([a\x{c0}]*?)aa/8 a\x{c0}aaaa/ 0: a\x{c0}aa 1: a\x{c0} /^([a\x{c0}]*?)aa/8 a\x{c0}aaaa/ 0: a\x{c0}aa 1: a\x{c0} a\x{c0}a\x{c0}aaa/ 0: a\x{c0}a\x{c0}aa 1: a\x{c0}a\x{c0} /^([a\x{c0}]*)aa/8 a\x{c0}aaaa/ 0: a\x{c0}aaaa 1: a\x{c0}aa a\x{c0}a\x{c0}aaa/ 0: a\x{c0}a\x{c0}aaa 1: a\x{c0}a\x{c0}a /^([a\x{c0}]*)a\x{c0}/8 a\x{c0}aaaa/ 0: a\x{c0} 1: a\x{c0}a\x{c0}aaa/ 0: a\x{c0}a\x{c0} 1: a\x{c0} /A*/g8 AAB\x{123}BAA 0: AA 0: 0: 0: 0: AA 0: /(abc)\1/8i abc No match /(abc)\1/8 abc No match /a(*:a\x{1234}b)/8K abc 0: a MK: a\x{1234}b /a(*:a£b)/8K abc 0: a MK: a\x{a3}b /-- End of testinput4 --/ pcre-8.31/testdata/testoutput50000644000222100022210000010724611767404463013412 00000000000000/-- This set of tests checks the API, internals, and non-Perl stuff for UTF support, excluding Unicode properties. However, tests that give different results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/ /\x{110000}/8DZ Failed: character value in \x{...} sequence is too large at offset 9 /\x{ffffffff}/8 Failed: character value in \x{...} sequence is too large at offset 11 /\x{100000000}/8 Failed: character value in \x{...} sequence is too large at offset 12 /\x{d800}/8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /\x{dfff}/8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /\x{d7ff}/8 /\x{e000}/8 /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd 0: \x{100}a\x{1234} /\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 ------------------------------------------------------------------ Bra A\x{2262}\x{391}. Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'A' Need char = '.' \x{0041}\x{2262}\x{0391}\x{002e} 0: A\x{2262}\x{391}. /.{3,5}X/DZ8 ------------------------------------------------------------------ Bra Any{3} Any{0,2} X Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char Need char = 'X' \x{212ab}\x{212ab}\x{212ab}\x{861}X 0: \x{212ab}\x{212ab}\x{212ab}\x{861}X /.{3,5}?/DZ8 ------------------------------------------------------------------ Bra Any{3} Any{0,2}? Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char \x{212ab}\x{212ab}\x{212ab}\x{861} 0: \x{212ab}\x{212ab}\x{212ab} /(?<=\C)X/8 Failed: \C not allowed in lookbehind assertion at offset 6 /^[ab]/8DZ ------------------------------------------------------------------ Bra ^ [ab] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored utf No first char No need char bar 0: b *** Failers No match c No match \x{ff} No match \x{100} No match /^[^ab]/8DZ ------------------------------------------------------------------ Bra ^ [\x00-`c-\xff] (neg) Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored utf No first char No need char c 0: c \x{ff} 0: \x{ff} \x{100} 0: \x{100} *** Failers 0: * aaa No match /\x{100}*(\d+|"(?1)")/8 1234 0: 1234 1: 1234 "1234" 0: "1234" 1: "1234" \x{100}1234 0: \x{100}1234 1: 1234 "\x{100}1234" 0: \x{100}1234 1: 1234 \x{100}\x{100}12ab 0: \x{100}\x{100}12 1: 12 \x{100}\x{100}"12" 0: \x{100}\x{100}"12" 1: "12" *** Failers No match \x{100}\x{100}abcd No match /\x{100}*/8DZ ------------------------------------------------------------------ Bra \x{100}* Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /a\x{100}*/8DZ ------------------------------------------------------------------ Bra a \x{100}* Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'a' No need char /ab\x{100}*/8DZ ------------------------------------------------------------------ Bra ab \x{100}* Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'a' Need char = 'b' /\x{100}*A/8DZ ------------------------------------------------------------------ Bra \x{100}*+ A Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char Need char = 'A' A 0: A /\x{100}*\d(?R)/8DZ ------------------------------------------------------------------ Bra \x{100}*+ \d Recurse Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /[Z\x{100}]/8DZ ------------------------------------------------------------------ Bra [Z\x{100}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char Z\x{100} 0: Z \x{100} 0: \x{100} \x{100}Z 0: \x{100} *** Failers No match /[\x{200}-\x{100}]/8 Failed: range out of order in character class at offset 15 /[Ä€-Ä„]/8 \x{100} 0: \x{100} \x{104} 0: \x{104} *** Failers No match \x{105} No match \x{ff} No match /[z-\x{100}]/8DZ ------------------------------------------------------------------ Bra [z-\x{100}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /[z\Qa-d]Ä€\E]/8DZ ------------------------------------------------------------------ Bra [\-\]adz\x{100}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char \x{100} 0: \x{100} Ä€ 0: \x{100} /[\xFF]/DZ ------------------------------------------------------------------ Bra \xff Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = \xff No need char >\xff< 0: \xff /[^\xFF]/DZ ------------------------------------------------------------------ Bra [^\xff] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[Ä-Ü]/8 Ö # Matches without Study 0: \x{d6} \x{d6} 0: \x{d6} /[Ä-Ü]/8S Ö <-- Same with Study 0: \x{d6} \x{d6} 0: \x{d6} /[\x{c4}-\x{dc}]/8 Ö # Matches without Study 0: \x{d6} \x{d6} 0: \x{d6} /[\x{c4}-\x{dc}]/8S Ö <-- Same with Study 0: \x{d6} \x{d6} 0: \x{d6} /[^\x{100}]abc(xyz(?1))/8DZ ------------------------------------------------------------------ Bra [^\x{100}] abc CBra 1 xyz Recurse Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char Need char = 'z' /[ab\x{100}]abc(xyz(?1))/8DZ ------------------------------------------------------------------ Bra [ab\x{100}] abc CBra 1 xyz Recurse Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf No first char Need char = 'z' /(\x{100}(b(?2)c))?/DZ8 ------------------------------------------------------------------ Bra Brazero CBra 1 \x{100} CBra 2 b Recurse c Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf No first char No need char /(\x{100}(b(?2)c)){0,2}/DZ8 ------------------------------------------------------------------ Bra Brazero Bra CBra 1 \x{100} CBra 2 b Recurse c Ket Ket Brazero CBra 1 \x{100} CBra 2 b Recurse c Ket Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf No first char No need char /(\x{100}(b(?1)c))?/DZ8 ------------------------------------------------------------------ Bra Brazero CBra 1 \x{100} CBra 2 b Recurse c Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf No first char No need char /(\x{100}(b(?1)c)){0,2}/DZ8 ------------------------------------------------------------------ Bra Brazero Bra CBra 1 \x{100} CBra 2 b Recurse c Ket Ket Brazero CBra 1 \x{100} CBra 2 b Recurse c Ket Ket Ket Ket End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf No first char No need char /\W/8 A.B 0: . A\x{100}B 0: \x{100} /\w/8 \x{100}X 0: X /^\ሴ/8DZ ------------------------------------------------------------------ Bra ^ \x{1234} Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored utf No first char No need char /\x{100}*\d/8DZ ------------------------------------------------------------------ Bra \x{100}*+ \d Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /\x{100}*\s/8DZ ------------------------------------------------------------------ Bra \x{100}*+ \s Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /\x{100}*\w/8DZ ------------------------------------------------------------------ Bra \x{100}*+ \w Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /\x{100}*\D/8DZ ------------------------------------------------------------------ Bra \x{100}* \D Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /\x{100}*\S/8DZ ------------------------------------------------------------------ Bra \x{100}* \S Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /\x{100}*\W/8DZ ------------------------------------------------------------------ Bra \x{100}* \W Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() A (x) (?41) B/8x AxxB Matched, but too many substrings 0: AxxB 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: /^[\x{100}\E-\Q\E\x{150}]/BZ8 ------------------------------------------------------------------ Bra ^ [\x{100}-\x{150}] Ket End ------------------------------------------------------------------ /^[\QÄ€\E-\QÅ\E]/BZ8 ------------------------------------------------------------------ Bra ^ [\x{100}-\x{150}] Ket End ------------------------------------------------------------------ /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc7 0: abc8 0: abc9 /abc.$/mgx8 abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc7 0: abc8 0: abc9 /^a\Rb/8 a\nb 0: a\x{0a}b a\rb 0: a\x{0d}b a\r\nb 0: a\x{0d}\x{0a}b a\x0bb 0: a\x{0b}b a\x0cb 0: a\x{0c}b a\x{85}b 0: a\x{85}b a\x{2028}b 0: a\x{2028}b a\x{2029}b 0: a\x{2029}b ** Failers No match a\n\rb No match /^a\R*b/8 ab 0: ab a\nb 0: a\x{0a}b a\rb 0: a\x{0d}b a\r\nb 0: a\x{0d}\x{0a}b a\x0bb 0: a\x{0b}b a\x0c\x{2028}\x{2029}b 0: a\x{0c}\x{2028}\x{2029}b a\x{85}b 0: a\x{85}b a\n\rb 0: a\x{0a}\x{0d}b a\n\r\x{85}\x0cb 0: a\x{0a}\x{0d}\x{85}\x{0c}b /^a\R+b/8 a\nb 0: a\x{0a}b a\rb 0: a\x{0d}b a\r\nb 0: a\x{0d}\x{0a}b a\x0bb 0: a\x{0b}b a\x0c\x{2028}\x{2029}b 0: a\x{0c}\x{2028}\x{2029}b a\x{85}b 0: a\x{85}b a\n\rb 0: a\x{0a}\x{0d}b a\n\r\x{85}\x0cb 0: a\x{0a}\x{0d}\x{85}\x{0c}b ** Failers No match ab No match /^a\R{1,3}b/8 a\nb 0: a\x{0a}b a\n\rb 0: a\x{0a}\x{0d}b a\n\r\x{85}b 0: a\x{0a}\x{0d}\x{85}b a\r\n\r\nb 0: a\x{0d}\x{0a}\x{0d}\x{0a}b a\r\n\r\n\r\nb 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b a\n\r\n\rb 0: a\x{0a}\x{0d}\x{0a}\x{0d}b a\n\n\r\nb 0: a\x{0a}\x{0a}\x{0d}\x{0a}b ** Failers No match a\n\n\n\rb No match a\r No match /\H\h\V\v/8 X X\x0a 0: X X\x{0a} X\x09X\x0b 0: X\x{09}X\x{0b} ** Failers No match \x{a0} X\x0a No match /\H*\h+\V?\v{3,4}/8 \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} \x09\x20\x{a0}\x0a\x0b\x0c 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} ** Failers No match \x09\x20\x{a0}\x0a\x0b No match /\H\h\V\v/8 \x{3001}\x{3000}\x{2030}\x{2028} 0: \x{3001}\x{3000}\x{2030}\x{2028} X\x{180e}X\x{85} 0: X\x{180e}X\x{85} ** Failers No match \x{2009} X\x0a No match /\H*\h+\V?\v{3,4}/8 \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d} \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028} \x09\x20\x{202f}\x0a\x0b\x0c 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} ** Failers No match \x09\x{200a}\x{a0}\x{2028}\x0b No match /[\h]/8BZ ------------------------------------------------------------------ Bra [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] Ket End ------------------------------------------------------------------ >\x{1680} 0: \x{1680} /[\h]{3,}/8BZ ------------------------------------------------------------------ Bra [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,} Ket End ------------------------------------------------------------------ >\x{1680}\x{180e}\x{2000}\x{2003}\x{200a}\x{202f}\x{205f}\x{3000}< 0: \x{1680}\x{180e}\x{2000}\x{2003}\x{200a}\x{202f}\x{205f}\x{3000} /[\v]/8BZ ------------------------------------------------------------------ Bra [\x0a-\x0d\x85\x{2028}-\x{2029}] Ket End ------------------------------------------------------------------ /[\H]/8BZ ------------------------------------------------------------------ Bra [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}] Ket End ------------------------------------------------------------------ /[\V]/8BZ ------------------------------------------------------------------ Bra [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}] Ket End ------------------------------------------------------------------ /.*$/8 \x{1ec5} 0: \x{1ec5} /a\Rb/I8 Capturing subpattern count = 0 Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b ** Failers No match a\x{85}b No match a\x0bb No match /a\Rb/I8 Capturing subpattern count = 0 Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b a\x{85}b 0: a\x{85}b a\x0bb 0: a\x{0b}b ** Failers No match a\x{85}b\ No match a\x0bb\ No match /a\R?b/I8 Capturing subpattern count = 0 Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b ** Failers No match a\x{85}b No match a\x0bb No match /a\R?b/I8 Capturing subpattern count = 0 Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b a\x{85}b 0: a\x{85}b a\x0bb 0: a\x{0b}b ** Failers No match a\x{85}b\ No match a\x0bb\ No match /.*a.*=.b.*/8 QQQ\x{2029}ABCaXYZ=!bPQR 0: ABCaXYZ=!bPQR ** Failers No match a\x{2029}b No match \x61\xe2\x80\xa9\x62 No match /[[:a\x{100}b:]]/8 Failed: unknown POSIX class name at offset 3 /a[^]b/8 a\x{1234}b 0: a\x{1234}b a\nb 0: a\x{0a}b ** Failers No match ab No match /a[^]+b/8 aXb 0: aXb a\nX\nX\x{1234}b 0: a\x{0a}X\x{0a}X\x{1234}b ** Failers No match ab No match /(\x{de})\1/ \x{de}\x{de} 0: \xde\xde 1: \xde /X/8f A\x{1ec5}ABCXYZ 0: X /Xa{2,4}b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /Xa{2,4}?b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /Xa{2,4}+b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X\x{123}{2,4}b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X\x{123}{2,4}?b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X\x{123}{2,4}+b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X\x{123}{2,4}b/8 Xx\P No match X\x{123}x\P No match X\x{123}\x{123}x\P No match X\x{123}\x{123}\x{123}x\P No match X\x{123}\x{123}\x{123}\x{123}x\P No match /X\x{123}{2,4}?b/8 Xx\P No match X\x{123}x\P No match X\x{123}\x{123}x\P No match X\x{123}\x{123}\x{123}x\P No match X\x{123}\x{123}\x{123}\x{123}x\P No match /X\x{123}{2,4}+b/8 Xx\P No match X\x{123}x\P No match X\x{123}\x{123}x\P No match X\x{123}\x{123}\x{123}x\P No match X\x{123}\x{123}\x{123}\x{123}x\P No match /X\d{2,4}b/8 X\P Partial match: X X3\P Partial match: X3 X33\P Partial match: X33 X333\P Partial match: X333 X3333\P Partial match: X3333 /X\d{2,4}?b/8 X\P Partial match: X X3\P Partial match: X3 X33\P Partial match: X33 X333\P Partial match: X333 X3333\P Partial match: X3333 /X\d{2,4}+b/8 X\P Partial match: X X3\P Partial match: X3 X33\P Partial match: X33 X333\P Partial match: X333 X3333\P Partial match: X3333 /X\D{2,4}b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X\D{2,4}?b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X\D{2,4}+b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X\D{2,4}b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X\D{2,4}?b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X\D{2,4}+b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X[abc]{2,4}b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X[abc]{2,4}?b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X[abc]{2,4}+b/8 X\P Partial match: X Xa\P Partial match: Xa Xaa\P Partial match: Xaa Xaaa\P Partial match: Xaaa Xaaaa\P Partial match: Xaaaa /X[abc\x{123}]{2,4}b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X[abc\x{123}]{2,4}?b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X[abc\x{123}]{2,4}+b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X[^a]{2,4}b/8 X\P Partial match: X Xz\P Partial match: Xz Xzz\P Partial match: Xzz Xzzz\P Partial match: Xzzz Xzzzz\P Partial match: Xzzzz /X[^a]{2,4}?b/8 X\P Partial match: X Xz\P Partial match: Xz Xzz\P Partial match: Xzz Xzzz\P Partial match: Xzzz Xzzzz\P Partial match: Xzzzz /X[^a]{2,4}+b/8 X\P Partial match: X Xz\P Partial match: Xz Xzz\P Partial match: Xzz Xzzz\P Partial match: Xzzz Xzzzz\P Partial match: Xzzzz /X[^a]{2,4}b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X[^a]{2,4}?b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /X[^a]{2,4}+b/8 X\P Partial match: X X\x{123}\P Partial match: X\x{123} X\x{123}\x{123}\P Partial match: X\x{123}\x{123} X\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123} X\x{123}\x{123}\x{123}\x{123}\P Partial match: X\x{123}\x{123}\x{123}\x{123} /(Y)X\1{2,4}b/8 YX\P Partial match: YX YXY\P Partial match: YXY YXYY\P Partial match: YXYY YXYYY\P Partial match: YXYYY YXYYYY\P Partial match: YXYYYY /(Y)X\1{2,4}?b/8 YX\P Partial match: YX YXY\P Partial match: YXY YXYY\P Partial match: YXYY YXYYY\P Partial match: YXYYY YXYYYY\P Partial match: YXYYYY /(Y)X\1{2,4}+b/8 YX\P Partial match: YX YXY\P Partial match: YXY YXYY\P Partial match: YXYY YXYYY\P Partial match: YXYYY YXYYYY\P Partial match: YXYYYY /(\x{123})X\1{2,4}b/8 \x{123}X\P Partial match: \x{123}X \x{123}X\x{123}\P Partial match: \x{123}X\x{123} \x{123}X\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123} \x{123}X\x{123}\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123}\x{123} \x{123}X\x{123}\x{123}\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123}\x{123}\x{123} /(\x{123})X\1{2,4}?b/8 \x{123}X\P Partial match: \x{123}X \x{123}X\x{123}\P Partial match: \x{123}X\x{123} \x{123}X\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123} \x{123}X\x{123}\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123}\x{123} \x{123}X\x{123}\x{123}\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123}\x{123}\x{123} /(\x{123})X\1{2,4}+b/8 \x{123}X\P Partial match: \x{123}X \x{123}X\x{123}\P Partial match: \x{123}X\x{123} \x{123}X\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123} \x{123}X\x{123}\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123}\x{123} \x{123}X\x{123}\x{123}\x{123}\x{123}\P Partial match: \x{123}X\x{123}\x{123}\x{123}\x{123} /\bthe cat\b/8 the cat\P 0: the cat the cat\P\P Partial match: the cat /abcd*/8 xxxxabcd\P 0: abcd xxxxabcd\P\P Partial match: abcd /abcd*/i8 xxxxabcd\P 0: abcd xxxxabcd\P\P Partial match: abcd XXXXABCD\P 0: ABCD XXXXABCD\P\P Partial match: ABCD /abc\d*/8 xxxxabc1\P 0: abc1 xxxxabc1\P\P Partial match: abc1 /(a)bc\1*/8 xxxxabca\P 0: abca 1: a xxxxabca\P\P Partial match: abca /abc[de]*/8 xxxxabcde\P 0: abcde xxxxabcde\P\P Partial match: abcde /X\W{3}X/8 \PX Partial match: X /\sxxx\s/8T1 AB\x{85}xxx\x{a0}XYZ 0: \x{85}xxx\x{a0} AB\x{a0}xxx\x{85}XYZ 0: \x{a0}xxx\x{85} /\S \S/8T1 \x{a2} \x{84} 0: \x{a2} \x{84} 'A#хц'8xBZ ------------------------------------------------------------------ Bra A Ket End ------------------------------------------------------------------ 'A#хц PQ'8xBZ ------------------------------------------------------------------ Bra APQ Ket End ------------------------------------------------------------------ /a+#Ñ…aa z#XX?/8xBZ ------------------------------------------------------------------ Bra a++ z Ket End ------------------------------------------------------------------ /a+#Ñ…aa z#Ñ…?/8xBZ ------------------------------------------------------------------ Bra a++ z Ket End ------------------------------------------------------------------ /\g{A}xxx#bXX(?'A'123) (?'A'456)/8xBZ ------------------------------------------------------------------ Bra \1 xxx CBra 1 456 Ket Ket End ------------------------------------------------------------------ /\g{A}xxx#bÑ…(?'A'123) (?'A'456)/8xBZ ------------------------------------------------------------------ Bra \1 xxx CBra 1 456 Ket Ket End ------------------------------------------------------------------ /^\cÄ£/8 Failed: \c must be followed by an ASCII character at offset 3 /(\R*)(.)/s8 \r\n 0: \x{0d} 1: 2: \x{0d} \r\r\n\n\r 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} 1: \x{0d}\x{0d}\x{0a}\x{0a} 2: \x{0d} \r\r\n\n\r\n 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} 1: \x{0d}\x{0d}\x{0a}\x{0a} 2: \x{0d} /(\R)*(.)/s8 \r\n 0: \x{0d} 1: 2: \x{0d} \r\r\n\n\r 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} 1: \x{0a} 2: \x{0d} \r\r\n\n\r\n 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} 1: \x{0a} 2: \x{0d} /[^\x{1234}]+/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 1 No set of starting bytes /[^\x{1234}]+?/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 1 No set of starting bytes /[^\x{1234}]++/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 1 No set of starting bytes /[^\x{1234}]{2}/iS8I Capturing subpattern count = 0 Options: caseless utf No first char No need char Subject length lower bound = 2 No set of starting bytes // Failed: inconsistent NEWLINE options at offset 0 /f.*/ \P\Pfor Partial match: for /f.*/s \P\Pfor Partial match: for /f.*/8 \P\Pfor Partial match: for /f.*/8s \P\Pfor Partial match: for /\x{d7ff}\x{e000}/8 /\x{d800}/8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /\x{dfff}/8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /\h+/8 \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} 0: \x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} 0: \x{200a}\x{a0}\x{2000} /[\h\x{e000}]+/8BZ ------------------------------------------------------------------ Bra [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]+ Ket End ------------------------------------------------------------------ \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} 0: \x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} 0: \x{200a}\x{a0}\x{2000} /\H+/8 \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} 0: \x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} 0: \x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} 0: \x{202e}\x{2030}\x{205e}\x{2060} \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} 0: \x{9f}\x{a1}\x{2fff}\x{3001} /[\H\x{d7ff}]+/8BZ ------------------------------------------------------------------ Bra [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]+ Ket End ------------------------------------------------------------------ \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} 0: \x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} 0: \x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} 0: \x{202e}\x{2030}\x{205e}\x{2060} \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} 0: \x{9f}\x{a1}\x{2fff}\x{3001} /\v+/8 \x{2027}\x{2030}\x{2028}\x{2029} 0: \x{2028}\x{2029} \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} /[\v\x{e000}]+/8BZ ------------------------------------------------------------------ Bra [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]+ Ket End ------------------------------------------------------------------ \x{2027}\x{2030}\x{2028}\x{2029} 0: \x{2028}\x{2029} \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} /\V+/8 \x{2028}\x{2029}\x{2027}\x{2030} 0: \x{2027}\x{2030} \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} 0: \x{09}\x{0e}\x{84}\x{86} /[\V\x{d7ff}]+/8BZ ------------------------------------------------------------------ Bra [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]+ Ket End ------------------------------------------------------------------ \x{2028}\x{2029}\x{2027}\x{2030} 0: \x{2027}\x{2030} \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} 0: \x{09}\x{0e}\x{84}\x{86} /\R+/8 \x{2027}\x{2030}\x{2028}\x{2029} 0: \x{2028}\x{2029} \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} /(..)\1/8 ab\P Partial match: ab aba\P Partial match: aba abab\P 0: abab 1: ab /(..)\1/8i ab\P Partial match: ab abA\P Partial match: abA aBAb\P 0: aBAb 1: aB /(..)\1{2,}/8 ab\P Partial match: ab aba\P Partial match: aba abab\P Partial match: abab ababa\P Partial match: ababa ababab\P 0: ababab 1: ab ababab\P\P Partial match: ababab abababa\P 0: ababab 1: ab abababa\P\P Partial match: abababa /(..)\1{2,}/8i ab\P Partial match: ab aBa\P Partial match: aBa aBAb\P Partial match: aBAb AbaBA\P Partial match: AbaBA abABAb\P 0: abABAb 1: ab aBAbaB\P\P Partial match: aBAbaB abABabA\P 0: abABab 1: ab abaBABa\P\P Partial match: abaBABa /(..)\1{2,}?x/8i ab\P Partial match: ab abA\P Partial match: abA aBAb\P Partial match: aBAb abaBA\P Partial match: abaBA abAbaB\P Partial match: abAbaB abaBabA\P Partial match: abaBabA abAbABaBx\P 0: abAbABaBx 1: ab /./8 \r\P 0: \x{0d} \r\P\P Partial match: \x{0d} /.{2,3}/8 \r\P Partial match: \x{0d} \r\P\P Partial match: \x{0d} \r\r\P 0: \x{0d}\x{0d} \r\r\P\P Partial match: \x{0d}\x{0d} \r\r\r\P 0: \x{0d}\x{0d}\x{0d} \r\r\r\P\P Partial match: \x{0d}\x{0d}\x{0d} /.{2,3}?/8 \r\P Partial match: \x{0d} \r\P\P Partial match: \x{0d} \r\r\P 0: \x{0d}\x{0d} \r\r\P\P Partial match: \x{0d}\x{0d} \r\r\r\P 0: \x{0d}\x{0d} \r\r\r\P\P 0: \x{0d}\x{0d} /[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ ------------------------------------------------------------------ Bra [^\x{100}] [^\x{1234}] [^\x{ffff}] [^\x{10000}] [^\x{10ffff}] Ket End ------------------------------------------------------------------ /[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi ------------------------------------------------------------------ Bra /i [^\x{100}] /i [^\x{1234}] /i [^\x{ffff}] /i [^\x{10000}] /i [^\x{10ffff}] Ket End ------------------------------------------------------------------ /[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ ------------------------------------------------------------------ Bra [^\x{100}]* [^\x{10000}]+ [^\x{10ffff}]?? [^\x{8000}]{4} [^\x{8000}]* [^\x{7fff}]{2} [^\x{7fff}]{0,7}? [^\x{fffff}]{5} [^\x{fffff}]?+ Ket End ------------------------------------------------------------------ /[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi ------------------------------------------------------------------ Bra /i [^\x{100}]* /i [^\x{10000}]+ /i [^\x{10ffff}]?? /i [^\x{8000}]{4} /i [^\x{8000}]* /i [^\x{7fff}]{2} /i [^\x{7fff}]{0,7}? Once /i [^\x{fffff}]{5} /i [^\x{fffff}]? Ket Ket End ------------------------------------------------------------------ /(?<=\x{1234}\x{1234})\bxy/I8 Capturing subpattern count = 0 Options: utf First char = 'x' Need char = 'y' Max lookbehind = 2 /(?8BZ ------------------------------------------------------------------ Bra \x{100} Ket End ------------------------------------------------------------------ /[\u0100-\u0200]/8BZ ------------------------------------------------------------------ Bra [\x{100}-\x{200}] Ket End ------------------------------------------------------------------ /\ud800/8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5 /-- End of testinput5 --/ pcre-8.31/testdata/testoutput60000644000222100022210000004740111723162171013374 00000000000000/-- This set of tests is for Unicode property support. It is compatible with Perl >= 5.10, but not 5.8 because it tests some extra properties that are not in the earlier release. --/ /^\pC\pL\pM\pN\pP\pS\pZ\s+/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09} /^>\pZ+/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f} /^>[[:space:]]*/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09}\x{0b} /^>[[:blank:]]*/8W >\x{20}\x{a0}\x{1680}\x{180e}\x{2000}\x{202f}\x{9}\x{b}\x{2028} 0: > \x{a0}\x{1680}\x{180e}\x{2000}\x{202f}\x{09} /^[[:alpha:]]*/8W Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d} 0: Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d} /^[[:alnum:]]*/8W Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d}1\x{660}\x{bef}\x{16ee} 0: Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d}1\x{660}\x{bef}\x{16ee} /^[[:cntrl:]]*/8W \x{0}\x{09}\x{1f}\x{7f}\x{9f} 0: \x{00}\x{09}\x{1f}\x{7f} /^[[:graph:]]*/8W A\x{a1}\x{a0} 0: A /^[[:print:]]*/8W A z\x{a0}\x{a1} 0: A z /^[[:punct:]]*/8W .+\x{a1}\x{a0} 0: .+ /\p{Zs}*?\R/ ** Failers No match a\xFCb No match /\p{Zs}*\R/ ** Failers No match a\xFCb No match /â±¥/8i â±¥ 0: \x{2c65} Ⱥx 0: \x{23a} Ⱥ 0: \x{23a} /[â±¥]/8i â±¥ 0: \x{2c65} Ⱥx 0: \x{23a} Ⱥ 0: \x{23a} /Ⱥ/8i Ⱥ 0: \x{23a} â±¥ 0: \x{2c65} /-- End of testinput6 --/ pcre-8.31/testdata/testoutput70000644000222100022210000006116311762204242013375 00000000000000/-- These tests for Unicode property support test PCRE's API and show some of the compiled code. They are not Perl-compatible. --/ /[\p{L}]/DZ ------------------------------------------------------------------ Bra [\p{L}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[\p{^L}]/DZ ------------------------------------------------------------------ Bra [\P{L}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[\P{L}]/DZ ------------------------------------------------------------------ Bra [\P{L}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[\P{^L}]/DZ ------------------------------------------------------------------ Bra [\p{L}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[abc\p{L}\x{0660}]/8DZ ------------------------------------------------------------------ Bra [a-c\p{L}\x{660}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char /[\p{Nd}]/8DZ ------------------------------------------------------------------ Bra [\p{Nd}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char 1234 0: 1 /[\p{Nd}+-]+/8DZ ------------------------------------------------------------------ Bra [+\-\p{Nd}]+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf No first char No need char 1234 0: 1234 12-34 0: 12-34 12+\x{661}-34 0: 12+\x{661}-34 ** Failers No match abcd No match /[\x{105}-\x{109}]/8iDZ ------------------------------------------------------------------ Bra [\x{104}-\x{109}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless utf No first char No need char \x{104} 0: \x{104} \x{105} 0: \x{105} \x{109} 0: \x{109} ** Failers No match \x{100} No match \x{10a} No match /[z-\x{100}]/8iDZ ------------------------------------------------------------------ Bra [Z\x{39c}\x{178}z-\x{101}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless utf No first char No need char Z 0: Z z 0: z \x{39c} 0: \x{39c} \x{178} 0: \x{178} | 0: | \x{80} 0: \x{80} \x{ff} 0: \x{ff} \x{100} 0: \x{100} \x{101} 0: \x{101} ** Failers No match \x{102} No match Y No match y No match /[z-\x{100}]/8DZi ------------------------------------------------------------------ Bra [Z\x{39c}\x{178}z-\x{101}] Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless utf No first char No need char /(?:[\PPa*]*){8,}/ /[\P{Any}]/BZ ------------------------------------------------------------------ Bra [\P{Any}] Ket End ------------------------------------------------------------------ /[\P{Any}\E]/BZ ------------------------------------------------------------------ Bra [\P{Any}] Ket End ------------------------------------------------------------------ /(\P{Yi}+\277)/ /(\P{Yi}+\277)?/ /(?<=\P{Yi}{3}A)X/ /\p{Yi}+(\P{Yi}+)(?1)/ /(\P{Yi}{2}\277)?/ /[\P{Yi}A]/ /[\P{Yi}\P{Yi}\P{Yi}A]/ /[^\P{Yi}A]/ /[^\P{Yi}\P{Yi}\P{Yi}A]/ /(\P{Yi}*\277)*/ /(\P{Yi}*?\277)*/ /(\p{Yi}*+\277)*/ /(\P{Yi}?\277)*/ /(\P{Yi}??\277)*/ /(\p{Yi}?+\277)*/ /(\P{Yi}{0,3}\277)*/ /(\P{Yi}{0,3}?\277)*/ /(\p{Yi}{0,3}+\277)*/ /\p{Zl}{2,3}+/8BZ ------------------------------------------------------------------ Bra prop Zl {2} prop Zl ?+ Ket End ------------------------------------------------------------------ \xe2\x80\xa8\xe2\x80\xa8 0: \x{2028}\x{2028} \x{2028}\x{2028}\x{2028} 0: \x{2028}\x{2028}\x{2028} /\p{Zl}/8BZ ------------------------------------------------------------------ Bra prop Zl Ket End ------------------------------------------------------------------ /\p{Lu}{3}+/8BZ ------------------------------------------------------------------ Bra prop Lu {3} Ket End ------------------------------------------------------------------ /\pL{2}+/8BZ ------------------------------------------------------------------ Bra prop L {2} Ket End ------------------------------------------------------------------ /\p{Cc}{2}+/8BZ ------------------------------------------------------------------ Bra prop Cc {2} Ket End ------------------------------------------------------------------ /^\p{Cs}/8 \?\x{dfff} 0: \x{dfff} ** Failers No match \x{09f} No match /^\p{Sc}+/8 $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} 0: $\x{a2}\x{a3}\x{a4}\x{a5} \x{9f2} 0: \x{9f2} ** Failers No match X No match \x{2c2} No match /^\p{Zs}/8 \ \ 0: \x{a0} 0: \x{a0} \x{1680} 0: \x{1680} \x{180e} 0: \x{180e} \x{2000} 0: \x{2000} \x{2001} 0: \x{2001} ** Failers No match \x{2028} No match \x{200d} No match /-- These four are here rather than in test 6 because Perl has problems with the negative versions of the properties. --/ /\p{^Lu}/8i 1234 0: 1 ** Failers 0: * ABC No match /\P{Lu}/8i 1234 0: 1 ** Failers 0: * ABC No match /\p{Ll}/8i a 0: a Az 0: z ** Failers 0: a ABC No match /\p{Lu}/8i A 0: A a\x{10a0}B 0: \x{10a0} ** Failers 0: F a No match \x{1d00} No match /[\x{c0}\x{391}]/8i \x{c0} 0: \x{c0} \x{e0} 0: \x{e0} /-- The next two are special cases where the lengths of the different cases of the same character differ. The first went wrong with heap frame storage; the second was broken in all cases. --/ /^\x{023a}+?(\x{0130}+)/8i \x{023a}\x{2c65}\x{0130} 0: \x{23a}\x{2c65}\x{130} 1: \x{130} /^\x{023a}+([^X])/8i \x{023a}\x{2c65}X 0: \x{23a}\x{2c65} 1: \x{2c65} /\x{c0}+\x{116}+/8i \x{c0}\x{e0}\x{116}\x{117} 0: \x{c0}\x{e0}\x{116}\x{117} /[\x{c0}\x{116}]+/8i \x{c0}\x{e0}\x{116}\x{117} 0: \x{c0}\x{e0}\x{116}\x{117} /(\x{de})\1/8i \x{de}\x{de} 0: \x{de}\x{de} 1: \x{de} \x{de}\x{fe} 0: \x{de}\x{fe} 1: \x{de} \x{fe}\x{fe} 0: \x{fe}\x{fe} 1: \x{fe} \x{fe}\x{de} 0: \x{fe}\x{de} 1: \x{fe} /^\x{c0}$/8i \x{c0} 0: \x{c0} \x{e0} 0: \x{e0} /^\x{e0}$/8i \x{c0} 0: \x{c0} \x{e0} 0: \x{e0} /-- The next two should be Perl-compatible, but it fails to match \x{e0}. PCRE will match it only with UCP support, because without that it has no notion of case for anything other than the ASCII letters. --/ /((?i)[\x{c0}])/8 \x{c0} 0: \x{c0} 1: \x{c0} \x{e0} 0: \x{e0} 1: \x{e0} /(?i:[\x{c0}])/8 \x{c0} 0: \x{c0} \x{e0} 0: \x{e0} /-- This should be Perl-compatible but Perl 5.11 gets \x{300} wrong. --/8 /^\X/8 A 0: A A\x{300}BC 0: A\x{300} A\x{300}\x{301}\x{302}BC 0: A\x{300}\x{301}\x{302} *** Failers 0: * \x{300} No match /-- These are PCRE's extra properties to help with Unicodizing \d etc. --/ /^\p{Xan}/8 ABCD 0: A 1234 0: 1 \x{6ca} 0: \x{6ca} \x{a6c} 0: \x{a6c} \x{10a7} 0: \x{10a7} ** Failers No match _ABC No match /^\p{Xan}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} ** Failers No match _ABC No match /^\p{Xan}+?/8 \x{6ca}\x{a6c}\x{10a7}_ 0: \x{6ca} /^\p{Xan}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} /^\p{Xan}{2,9}/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca} /^\p{Xan}{2,9}?/8 \x{6ca}\x{a6c}\x{10a7}_ 0: \x{6ca}\x{a6c} /^[\p{Xan}]/8 ABCD1234_ 0: A 1234abcd_ 0: 1 \x{6ca} 0: \x{6ca} \x{a6c} 0: \x{a6c} \x{10a7} 0: \x{10a7} ** Failers No match _ABC No match /^[\p{Xan}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} ** Failers No match _ABC No match /^>\p{Xsp}/8 >\x{1680}\x{2028}\x{0b} 0: >\x{1680} >\x{a0} 0: >\x{a0} ** Failers No match \x{0b} No match /^>\p{Xsp}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} /^>\p{Xsp}+?/8 >\x{1680}\x{2028}\x{0b} 0: >\x{1680} /^>\p{Xsp}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} /^>\p{Xsp}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} /^>\p{Xsp}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09} /^>[\p{Xsp}]/8 >\x{2028}\x{0b} 0: >\x{2028} /^>[\p{Xsp}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} /^>\p{Xps}/8 >\x{1680}\x{2028}\x{0b} 0: >\x{1680} >\x{a0} 0: >\x{a0} ** Failers No match \x{0b} No match /^>\p{Xps}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}+?/8 >\x{1680}\x{2028}\x{0b} 0: >\x{1680} /^>\p{Xps}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09} /^>[\p{Xps}]/8 >\x{2028}\x{0b} 0: >\x{2028} /^>[\p{Xps}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^\p{Xwd}/8 ABCD 0: A 1234 0: 1 \x{6ca} 0: \x{6ca} \x{a6c} 0: \x{a6c} \x{10a7} 0: \x{10a7} _ABC 0: _ ** Failers No match [] No match /^\p{Xwd}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xwd}+?/8 \x{6ca}\x{a6c}\x{10a7}_ 0: \x{6ca} /^\p{Xwd}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xwd}{2,9}/8 A_B12\x{6ca}\x{a6c}\x{10a7} 0: A_B12\x{6ca}\x{a6c}\x{10a7} /^\p{Xwd}{2,9}?/8 \x{6ca}\x{a6c}\x{10a7}_ 0: \x{6ca}\x{a6c} /^[\p{Xwd}]/8 ABCD1234_ 0: A 1234abcd_ 0: 1 \x{6ca} 0: \x{6ca} \x{a6c} 0: \x{a6c} \x{10a7} 0: \x{10a7} _ABC 0: _ ** Failers No match [] No match /^[\p{Xwd}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /-- A check not in UTF-8 mode --/ /^[\p{Xwd}]+/ ABCD1234_ 0: ABCD1234_ /-- Some negative checks --/ /^[\P{Xwd}]+/8 !.+\x{019}\x{35a}AB 0: !.+\x{19}\x{35a} /^[\p{^Xwd}]+/8 !.+\x{019}\x{35a}AB 0: !.+\x{19}\x{35a} /[\D]/WBZ8 ------------------------------------------------------------------ Bra [\P{Nd}] Ket End ------------------------------------------------------------------ 1\x{3c8}2 0: \x{3c8} /[\d]/WBZ8 ------------------------------------------------------------------ Bra [\p{Nd}] Ket End ------------------------------------------------------------------ >\x{6f4}< 0: \x{6f4} /[\S]/WBZ8 ------------------------------------------------------------------ Bra [\P{Xsp}] Ket End ------------------------------------------------------------------ \x{1680}\x{6f4}\x{1680} 0: \x{6f4} /[\s]/WBZ8 ------------------------------------------------------------------ Bra [\p{Xsp}] Ket End ------------------------------------------------------------------ >\x{1680}< 0: \x{1680} /[\W]/WBZ8 ------------------------------------------------------------------ Bra [\P{Xwd}] Ket End ------------------------------------------------------------------ A\x{1712}B 0: \x{1712} /[\w]/WBZ8 ------------------------------------------------------------------ Bra [\p{Xwd}] Ket End ------------------------------------------------------------------ >\x{1723}< 0: \x{1723} /\D/WBZ8 ------------------------------------------------------------------ Bra notprop Nd Ket End ------------------------------------------------------------------ 1\x{3c8}2 0: \x{3c8} /\d/WBZ8 ------------------------------------------------------------------ Bra prop Nd Ket End ------------------------------------------------------------------ >\x{6f4}< 0: \x{6f4} /\S/WBZ8 ------------------------------------------------------------------ Bra notprop Xsp Ket End ------------------------------------------------------------------ \x{1680}\x{6f4}\x{1680} 0: \x{6f4} /\s/WBZ8 ------------------------------------------------------------------ Bra prop Xsp Ket End ------------------------------------------------------------------ >\x{1680}> 0: \x{1680} /\W/WBZ8 ------------------------------------------------------------------ Bra notprop Xwd Ket End ------------------------------------------------------------------ A\x{1712}B 0: \x{1712} /\w/WBZ8 ------------------------------------------------------------------ Bra prop Xwd Ket End ------------------------------------------------------------------ >\x{1723}< 0: \x{1723} /[[:alpha:]]/WBZ ------------------------------------------------------------------ Bra [\p{L}] Ket End ------------------------------------------------------------------ /[[:lower:]]/WBZ ------------------------------------------------------------------ Bra [\p{Ll}] Ket End ------------------------------------------------------------------ /[[:upper:]]/WBZ ------------------------------------------------------------------ Bra [\p{Lu}] Ket End ------------------------------------------------------------------ /[[:alnum:]]/WBZ ------------------------------------------------------------------ Bra [\p{Xan}] Ket End ------------------------------------------------------------------ /[[:ascii:]]/WBZ ------------------------------------------------------------------ Bra [\x00-\x7f] Ket End ------------------------------------------------------------------ /[[:cntrl:]]/WBZ ------------------------------------------------------------------ Bra [\x00-\x1f\x7f] Ket End ------------------------------------------------------------------ /[[:digit:]]/WBZ ------------------------------------------------------------------ Bra [\p{Nd}] Ket End ------------------------------------------------------------------ /[[:graph:]]/WBZ ------------------------------------------------------------------ Bra [!-~] Ket End ------------------------------------------------------------------ /[[:print:]]/WBZ ------------------------------------------------------------------ Bra [ -~] Ket End ------------------------------------------------------------------ /[[:punct:]]/WBZ ------------------------------------------------------------------ Bra [!-/:-@[-`{-~] Ket End ------------------------------------------------------------------ /[[:space:]]/WBZ ------------------------------------------------------------------ Bra [\p{Xps}] Ket End ------------------------------------------------------------------ /[[:word:]]/WBZ ------------------------------------------------------------------ Bra [\p{Xwd}] Ket End ------------------------------------------------------------------ /[[:xdigit:]]/WBZ ------------------------------------------------------------------ Bra [0-9A-Fa-f] Ket End ------------------------------------------------------------------ /-- Unicode properties for \b abd \B --/ /\b...\B/8W abc_ 0: abc \x{37e}abc\x{376} 0: abc \x{37e}\x{376}\x{371}\x{393}\x{394} 0: \x{376}\x{371}\x{393} !\x{c0}++\x{c1}\x{c2} 0: ++\x{c1} !\x{c0}+++++ 0: \x{c0}++ /-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ /\b...\B/8 abc_ 0: abc ** Failers 0: Fai \x{37e}abc\x{376} No match \x{37e}\x{376}\x{371}\x{393}\x{394} No match !\x{c0}++\x{c1}\x{c2} No match !\x{c0}+++++ No match /-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ /\b...\B/W abc_ 0: abc !\x{c0}++\x{c1}\x{c2} 0: ++\xc1 !\x{c0}+++++ 0: \xc0++ /-- Some of these are silly, but they check various combinations --/ /[[:^alpha:][:^cntrl:]]+/8WBZ ------------------------------------------------------------------ Bra [ -~\x80-\xff\P{L}]+ Ket End ------------------------------------------------------------------ 123 0: 123 abc 0: abc /[[:^cntrl:][:^alpha:]]+/8WBZ ------------------------------------------------------------------ Bra [ -~\x80-\xff\P{L}]+ Ket End ------------------------------------------------------------------ 123 0: 123 abc 0: abc /[[:alpha:]]+/8WBZ ------------------------------------------------------------------ Bra [\p{L}]+ Ket End ------------------------------------------------------------------ abc 0: abc /[[:^alpha:]\S]+/8WBZ ------------------------------------------------------------------ Bra [\P{L}\P{Xsp}]+ Ket End ------------------------------------------------------------------ 123 0: 123 abc 0: abc /[^\d]+/8WBZ ------------------------------------------------------------------ Bra [^\p{Nd}]+ Ket End ------------------------------------------------------------------ abc123 0: abc abc\x{123} 0: abc\x{123} \x{660}abc 0: abc /\p{Lu}+9\p{Lu}+B\p{Lu}+b/BZ ------------------------------------------------------------------ Bra prop Lu ++ 9 prop Lu + B prop Lu ++ b Ket End ------------------------------------------------------------------ /\p{^Lu}+9\p{^Lu}+B\p{^Lu}+b/BZ ------------------------------------------------------------------ Bra notprop Lu + 9 notprop Lu ++ B notprop Lu + b Ket End ------------------------------------------------------------------ /\P{Lu}+9\P{Lu}+B\P{Lu}+b/BZ ------------------------------------------------------------------ Bra notprop Lu + 9 notprop Lu ++ B notprop Lu + b Ket End ------------------------------------------------------------------ /\p{Han}+X\p{Greek}+\x{370}/BZ8 ------------------------------------------------------------------ Bra prop Han ++ X prop Greek + \x{370} Ket End ------------------------------------------------------------------ /\p{Xan}+!\p{Xan}+A/BZ ------------------------------------------------------------------ Bra prop Xan ++ ! prop Xan + A Ket End ------------------------------------------------------------------ /\p{Xsp}+!\p{Xsp}\t/BZ ------------------------------------------------------------------ Bra prop Xsp ++ ! prop Xsp \x09 Ket End ------------------------------------------------------------------ /\p{Xps}+!\p{Xps}\t/BZ ------------------------------------------------------------------ Bra prop Xps ++ ! prop Xps \x09 Ket End ------------------------------------------------------------------ /\p{Xwd}+!\p{Xwd}_/BZ ------------------------------------------------------------------ Bra prop Xwd ++ ! prop Xwd _ Ket End ------------------------------------------------------------------ /A+\p{N}A+\dB+\p{N}*B+\d*/WBZ ------------------------------------------------------------------ Bra A++ prop N A++ prop Nd B+ prop N *+ B+ prop Nd * Ket End ------------------------------------------------------------------ /-- These behaved oddly in Perl, so they are kept in this test --/ /(\x{23a}\x{23a}\x{23a})?\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} No match /(ȺȺȺ)?\1/8i ȺȺȺⱥⱥ No match /(\x{23a}\x{23a}\x{23a})?\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} 1: \x{23a}\x{23a}\x{23a} /(ȺȺȺ)?\1/8i ȺȺȺⱥⱥⱥ 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} 1: \x{23a}\x{23a}\x{23a} /(\x{23a}\x{23a}\x{23a})\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} No match /(ȺȺȺ)\1/8i ȺȺȺⱥⱥ No match /(\x{23a}\x{23a}\x{23a})\1/8i \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} 1: \x{23a}\x{23a}\x{23a} /(ȺȺȺ)\1/8i ȺȺȺⱥⱥⱥ 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} 1: \x{23a}\x{23a}\x{23a} /(\x{2c65}\x{2c65})\1/8i \x{2c65}\x{2c65}\x{23a}\x{23a} 0: \x{2c65}\x{2c65}\x{23a}\x{23a} 1: \x{2c65}\x{2c65} /(ⱥⱥ)\1/8i ⱥⱥȺȺ 0: \x{2c65}\x{2c65}\x{23a}\x{23a} 1: \x{2c65}\x{2c65} /(\x{23a}\x{23a}\x{23a})\1Y/8i X\x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}YZ 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}Y 1: \x{23a}\x{23a}\x{23a} /(\x{2c65}\x{2c65})\1Y/8i X\x{2c65}\x{2c65}\x{23a}\x{23a}YZ 0: \x{2c65}\x{2c65}\x{23a}\x{23a}Y 1: \x{2c65}\x{2c65} /-- --/ /-- These scripts weren't yet in Perl when I added Unicode 6.0.0 to PCRE --/ /^[\p{Batak}]/8 \x{1bc0} 0: \x{1bc0} \x{1bff} 0: \x{1bff} ** Failers No match \x{1bf4} No match /^[\p{Brahmi}]/8 \x{11000} 0: \x{11000} \x{1106f} 0: \x{1106f} ** Failers No match \x{1104e} No match /^[\p{Mandaic}]/8 \x{840} 0: \x{840} \x{85e} 0: \x{85e} ** Failers No match \x{85c} No match \x{85d} No match /-- --/ /(\X*)(.)/s8 A\x{300} 0: A 1: 2: A /^S(\X*)e(\X*)$/8 SteÌreÌo No match /^\X/8 ÌreÌo No match /^a\X41z/ aX41z 0: aX41z *** Failers No match aAz No match /(?<=ab\Cde)X/8 Failed: \C not allowed in lookbehind assertion at offset 10 /\X/ a\P 0: a a\P\P Partial match: a /\Xa/ aa\P 0: aa aa\P\P 0: aa /\X{2}/ aa\P 0: aa aa\P\P Partial match: aa /\X+a/ a\P Partial match: a aa\P 0: aa aa\P\P Partial match: aa /\X+?a/ a\P Partial match: a ab\P Partial match: ab aa\P 0: aa aa\P\P 0: aa aba\P 0: aba /-- These Unicode 6.1.0 scripts are not known to Perl. --/ /\p{Chakma}\d/8W \x{11100}\x{1113c} 0: \x{11100}\x{1113c} /\p{Takri}\d/8W \x{11680}\x{116c0} 0: \x{11680}\x{116c0} /^\X/8 A\P 0: A A\P\P Partial match: A A\x{300}\x{301}\P 0: A\x{300}\x{301} A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301} A\x{301}\P 0: A\x{301} A\x{301}\P\P Partial match: A\x{301} /^\X{2,3}/8 A\P Partial match: A A\P\P Partial match: A AA\P 0: AA AA\P\P Partial match: AA A\x{300}\x{301}\P Partial match: A\x{300}\x{301} A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301} A\x{300}\x{301}A\x{300}\x{301}\P 0: A\x{300}\x{301}A\x{300}\x{301} A\x{300}\x{301}A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301}A\x{300}\x{301} /^\X{2}/8 AA\P 0: AA AA\P\P Partial match: AA A\x{300}\x{301}A\x{300}\x{301}\P 0: A\x{300}\x{301}A\x{300}\x{301} A\x{300}\x{301}A\x{300}\x{301}\P\P Partial match: A\x{300}\x{301}A\x{300}\x{301} /^\X+/8 AA\P 0: AA AA\P\P Partial match: AA /^\X+?Z/8 AA\P Partial match: AA AA\P\P Partial match: AA /-- End of testinput7 --/ pcre-8.31/testdata/testoutput80000644000222100022210000036015011767425330013404 00000000000000/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running it. --/ /abc/ abc 0: abc /ab*c/ abc 0: abc abbbbc 0: abbbbc ac 0: ac /ab+c/ abc 0: abc abbbbbbc 0: abbbbbbc *** Failers No match ac No match ab No match /a*/ a 0: a 1: aaaaaaaaaaaaaaaaa 0: aaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaa 3: aaaaaaaaaaaaaa 4: aaaaaaaaaaaaa 5: aaaaaaaaaaaa 6: aaaaaaaaaaa 7: aaaaaaaaaa 8: aaaaaaaaa 9: aaaaaaaa 10: aaaaaaa 11: aaaaaa 12: aaaaa 13: aaaa 14: aaa 15: aa 16: a 17: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Matched, but too many subsidiary matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaa 3: aaaaaaaaaaaaaaaaaaaaaaaaaaa 4: aaaaaaaaaaaaaaaaaaaaaaaaaa 5: aaaaaaaaaaaaaaaaaaaaaaaaa 6: aaaaaaaaaaaaaaaaaaaaaaaa 7: aaaaaaaaaaaaaaaaaaaaaaa 8: aaaaaaaaaaaaaaaaaaaaaa 9: aaaaaaaaaaaaaaaaaaaaa 10: aaaaaaaaaaaaaaaaaaaa 11: aaaaaaaaaaaaaaaaaaa 12: aaaaaaaaaaaaaaaaaa 13: aaaaaaaaaaaaaaaaa 14: aaaaaaaaaaaaaaaa 15: aaaaaaaaaaaaaaa 16: aaaaaaaaaaaaaa 17: aaaaaaaaaaaaa 18: aaaaaaaaaaaa 19: aaaaaaaaaaa 20: aaaaaaaaaa 21: aaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F 0: /(a|abcd|african)/ a 0: a abcd 0: abcd 1: a african 0: african 1: a /^abc/ abcdef 0: abc *** Failers No match xyzabc No match xyz\nabc No match /^abc/m abcdef 0: abc xyz\nabc 0: abc *** Failers No match xyzabc No match /\Aabc/ abcdef 0: abc *** Failers No match xyzabc No match xyz\nabc No match /\Aabc/m abcdef 0: abc *** Failers No match xyzabc No match xyz\nabc No match /\Gabc/ abcdef 0: abc xyzabc\>3 0: abc *** Failers No match xyzabc No match xyzabc\>2 No match /x\dy\Dz/ x9yzz 0: x9yzz x0y+z 0: x0y+z *** Failers No match xyz No match xxy0z No match /x\sy\Sz/ x yzz 0: x yzz x y+z 0: x y+z *** Failers No match xyz No match xxyyz No match /x\wy\Wz/ xxy+z 0: xxy+z *** Failers No match xxy0z No match x+y+z No match /x.y/ x+y 0: x+y x-y 0: x-y *** Failers No match x\ny No match /x.y/s x+y 0: x+y x-y 0: x-y x\ny 0: x\x0ay /(a.b(?s)c.d|x.y)p.q/ a+bc+dp+q 0: a+bc+dp+q a+bc\ndp+q 0: a+bc\x0adp+q x\nyp+q 0: x\x0ayp+q *** Failers No match a\nbc\ndp+q No match a+bc\ndp\nq No match x\nyp\nq No match /a\d\z/ ba0 0: a0 *** Failers No match ba0\n No match ba0\ncd No match /a\d\z/m ba0 0: a0 *** Failers No match ba0\n No match ba0\ncd No match /a\d\Z/ ba0 0: a0 ba0\n 0: a0 *** Failers No match ba0\ncd No match /a\d\Z/m ba0 0: a0 ba0\n 0: a0 *** Failers No match ba0\ncd No match /a\d$/ ba0 0: a0 ba0\n 0: a0 *** Failers No match ba0\ncd No match /a\d$/m ba0 0: a0 ba0\n 0: a0 ba0\ncd 0: a0 *** Failers No match /abc/i abc 0: abc aBc 0: aBc ABC 0: ABC /[^a]/ abcd 0: b /ab?\w/ abz 0: abz 1: ab abbz 0: abb 1: ab azz 0: az /x{0,3}yz/ ayzq 0: yz axyzq 0: xyz axxyz 0: xxyz axxxyzq 0: xxxyz axxxxyzq 0: xxxyz *** Failers No match ax No match axx No match /x{3}yz/ axxxyzq 0: xxxyz axxxxyzq 0: xxxyz *** Failers No match ax No match axx No match ayzq No match axyzq No match axxyz No match /x{2,3}yz/ axxyz 0: xxyz axxxyzq 0: xxxyz axxxxyzq 0: xxxyz *** Failers No match ax No match axx No match ayzq No match axyzq No match /[^a]+/ bac 0: b bcdefax 0: bcdef 1: bcde 2: bcd 3: bc 4: b *** Failers 0: *** F 1: *** 2: *** 3: ** 4: * aaaaa No match /[^a]*/ bac 0: b 1: bcdefax 0: bcdef 1: bcde 2: bcd 3: bc 4: b 5: *** Failers 0: *** F 1: *** 2: *** 3: ** 4: * 5: aaaaa 0: /[^a]{3,5}/ xyz 0: xyz awxyza 0: wxyz 1: wxy abcdefa 0: bcdef 1: bcde 2: bcd abcdefghijk 0: bcdef 1: bcde 2: bcd *** Failers 0: *** F 1: *** 2: *** axya No match axa No match aaaaa No match /\d*/ 1234b567 0: 1234 1: 123 2: 12 3: 1 4: xyz 0: /\D*/ a1234b567 0: a 1: xyz 0: xyz 1: xy 2: x 3: /\d+/ ab1234c56 0: 1234 1: 123 2: 12 3: 1 *** Failers No match xyz No match /\D+/ ab123c56 0: ab 1: a *** Failers 0: *** Failers 1: *** Failer 2: *** Faile 3: *** Fail 4: *** Fai 5: *** Fa 6: *** F 7: *** 8: *** 9: ** 10: * 789 No match /\d?A/ 045ABC 0: 5A ABC 0: A *** Failers No match XYZ No match /\D?A/ ABC 0: A BAC 0: BA 9ABC 0: A *** Failers No match /a+/ aaaa 0: aaaa 1: aaa 2: aa 3: a /^.*xyz/ xyz 0: xyz ggggggggxyz 0: ggggggggxyz /^.+xyz/ abcdxyz 0: abcdxyz axyz 0: axyz *** Failers No match xyz No match /^.?xyz/ xyz 0: xyz cxyz 0: cxyz /^\d{2,3}X/ 12X 0: 12X 123X 0: 123X *** Failers No match X No match 1X No match 1234X No match /^[abcd]\d/ a45 0: a4 b93 0: b9 c99z 0: c9 d04 0: d0 *** Failers No match e45 No match abcd No match abcd1234 No match 1234 No match /^[abcd]*\d/ a45 0: a4 b93 0: b9 c99z 0: c9 d04 0: d0 abcd1234 0: abcd1 1234 0: 1 *** Failers No match e45 No match abcd No match /^[abcd]+\d/ a45 0: a4 b93 0: b9 c99z 0: c9 d04 0: d0 abcd1234 0: abcd1 *** Failers No match 1234 No match e45 No match abcd No match /^a+X/ aX 0: aX aaX 0: aaX /^[abcd]?\d/ a45 0: a4 b93 0: b9 c99z 0: c9 d04 0: d0 1234 0: 1 *** Failers No match abcd1234 No match e45 No match /^[abcd]{2,3}\d/ ab45 0: ab4 bcd93 0: bcd9 *** Failers No match 1234 No match a36 No match abcd1234 No match ee45 No match /^(abc)*\d/ abc45 0: abc4 abcabcabc45 0: abcabcabc4 42xyz 0: 4 *** Failers No match /^(abc)+\d/ abc45 0: abc4 abcabcabc45 0: abcabcabc4 *** Failers No match 42xyz No match /^(abc)?\d/ abc45 0: abc4 42xyz 0: 4 *** Failers No match abcabcabc45 No match /^(abc){2,3}\d/ abcabc45 0: abcabc4 abcabcabc45 0: abcabcabc4 *** Failers No match abcabcabcabc45 No match abc45 No match 42xyz No match /1(abc|xyz)2(?1)3/ 1abc2abc3456 0: 1abc2abc3 1abc2xyz3456 0: 1abc2xyz3 /^(a*\w|ab)=(a*\w|ab)/ ab=ab 0: ab=ab 1: ab=a /^(a*\w|ab)=(?1)/ ab=ab 0: ab=ab 1: ab=a /^([^()]|\((?1)*\))*$/ abc 0: abc a(b)c 0: a(b)c a(b(c))d 0: a(b(c))d *** Failers) No match a(b(c)d No match /^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3)a*)\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9 *** Failers No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x <> 0: <> 0: hij> 0: hij> hij> 0: def> 0: def> 0: <> *** Failers No match abcxyz 1 ^ ^ x 0: abcxyz 123abcxyz999 --->123abcxyz999 1 ^ ^ x 0: abcxyz /(ab|cd){3,4}/C ababab --->ababab +0 ^ (ab|cd){3,4} +1 ^ a +4 ^ c +2 ^^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +2 ^ ^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +2 ^ ^ b +3 ^ ^ | +12 ^ ^ +1 ^ ^ a +4 ^ ^ c 0: ababab abcdabcd --->abcdabcd +0 ^ (ab|cd){3,4} +1 ^ a +4 ^ c +2 ^^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +4 ^ ^ c +2 ^ ^ b +3 ^ ^ | +12 ^ ^ +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +12 ^ ^ 0: abcdabcd 1: abcdab abcdcdcdcdcd --->abcdcdcdcdcd +0 ^ (ab|cd){3,4} +1 ^ a +4 ^ c +2 ^^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +12 ^ ^ +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +12 ^ ^ 0: abcdcdcd 1: abcdcd /^abc/ abcdef 0: abc *** Failers No match abcdef\B No match /^(a*|xyz)/ bcd 0: aaabcd 0: aaa 1: aa 2: a 3: xyz 0: xyz 1: xyz\N 0: xyz *** Failers 0: bcd\N No match /xyz$/ xyz 0: xyz xyz\n 0: xyz *** Failers No match xyz\Z No match xyz\n\Z No match /xyz$/m xyz 0: xyz xyz\n 0: xyz abcxyz\npqr 0: xyz abcxyz\npqr\Z 0: xyz xyz\n\Z 0: xyz *** Failers No match xyz\Z No match /\Gabc/ abcdef 0: abc defabcxyz\>3 0: abc *** Failers No match defabcxyz No match /^abcdef/ ab\P Partial match: ab abcde\P Partial match: abcde abcdef\P 0: abcdef *** Failers No match abx\P No match /^a{2,4}\d+z/ a\P Partial match: a aa\P Partial match: aa aa2\P Partial match: aa2 aaa\P Partial match: aaa aaa23\P Partial match: aaa23 aaaa12345\P Partial match: aaaa12345 aa0z\P 0: aa0z aaaa4444444444444z\P 0: aaaa4444444444444z *** Failers No match az\P No match aaaaa\P No match a56\P No match /^abcdef/ abc\P Partial match: abc def\R 0: def /(?<=foo)bar/ xyzfo\P No match foob\P\>2 Partial match: foob foobar...\R\P\>4 0: ar xyzfo\P No match foobar\>2 0: bar *** Failers No match xyzfo\P No match obar\R No match /(ab*(cd|ef))+X/ adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z No match lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z Partial match: abbbbbbcdaefabbbbbbbefa cdabbbbbbbb\P\R\B\Z Partial match: cdabbbbbbbb efabbbbbbbbbbbbbbbb\P\R\B\Z Partial match: efabbbbbbbbbbbbbbbb bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z 0: bbbbbbbbbbbbcdX /(a|b)/SF>testsavedregex Compiled pattern written to testsavedregex Study data written to testsavedregex >>aaabxyzpqrrrabbxyyyypqAzz 0: aaabxyzpqrrrabbxyyyypqAzz >aaaabxyzpqrrrabbxyyyypqAzz 0: aaaabxyzpqrrrabbxyyyypqAzz >>>>abcxyzpqrrrabbxyyyypqAzz 0: abcxyzpqrrrabbxyyyypqAzz *** Failers No match abxyzpqrrabbxyyyypqAzz No match abxyzpqrrrrabbxyyyypqAzz No match abxyzpqrrrabxyyyypqAzz No match aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz No match aaaabcxyzzzzpqrrrabbbxyyypqAzz No match aaabcxyzpqrrrabbxyyyypqqqqqqqAzz No match /^(abc){1,2}zz/ abczz 0: abczz abcabczz 0: abcabczz *** Failers No match zz No match abcabcabczz No match >>abczz No match /^(b+?|a){1,2}?c/ bc 0: bc bbc 0: bbc bbbc 0: bbbc bac 0: bac bbac 0: bbac aac 0: aac abbbbbbbbbbbc 0: abbbbbbbbbbbc bbbbbbbbbbbac 0: bbbbbbbbbbbac *** Failers No match aaac No match abbbbbbbbbbbac No match /^(b+|a){1,2}c/ bc 0: bc bbc 0: bbc bbbc 0: bbbc bac 0: bac bbac 0: bbac aac 0: aac abbbbbbbbbbbc 0: abbbbbbbbbbbc bbbbbbbbbbbac 0: bbbbbbbbbbbac *** Failers No match aaac No match abbbbbbbbbbbac No match /^(b+|a){1,2}?bc/ bbc 0: bbc /^(b*|ba){1,2}?bc/ babc 0: babc bbabc 0: bbabc bababc 0: bababc *** Failers No match bababbc No match babababc No match /^(ba|b*){1,2}?bc/ babc 0: babc bbabc 0: bbabc bababc 0: bababc *** Failers No match bababbc No match babababc No match /^\ca\cA\c[\c{\c:/ \x01\x01\e;z 0: \x01\x01\x1b;z /^[ab\]cde]/ athing 0: a bthing 0: b ]thing 0: ] cthing 0: c dthing 0: d ething 0: e *** Failers No match fthing No match [thing No match \\thing No match /^[]cde]/ ]thing 0: ] cthing 0: c dthing 0: d ething 0: e *** Failers No match athing No match fthing No match /^[^ab\]cde]/ fthing 0: f [thing 0: [ \\thing 0: \ *** Failers 0: * athing No match bthing No match ]thing No match cthing No match dthing No match ething No match /^[^]cde]/ athing 0: a fthing 0: f *** Failers 0: * ]thing No match cthing No match dthing No match ething No match /^\/ 0: \x81 /^ÿ/ ÿ 0: \xff /^[0-9]+$/ 0 0: 0 1 0: 1 2 0: 2 3 0: 3 4 0: 4 5 0: 5 6 0: 6 7 0: 7 8 0: 8 9 0: 9 10 0: 10 100 0: 100 *** Failers No match abc No match /^.*nter/ enter 0: enter inter 0: inter uponter 0: uponter /^xxx[0-9]+$/ xxx0 0: xxx0 xxx1234 0: xxx1234 *** Failers No match xxx No match /^.+[0-9][0-9][0-9]$/ x123 0: x123 xx123 0: xx123 123456 0: 123456 *** Failers No match 123 No match x1234 0: x1234 /^.+?[0-9][0-9][0-9]$/ x123 0: x123 xx123 0: xx123 123456 0: 123456 *** Failers No match 123 No match x1234 0: x1234 /^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ abc!pqr=apquxz.ixr.zzz.ac.uk 0: abc!pqr=apquxz.ixr.zzz.ac.uk *** Failers No match !pqr=apquxz.ixr.zzz.ac.uk No match abc!=apquxz.ixr.zzz.ac.uk No match abc!pqr=apquxz:ixr.zzz.ac.uk No match abc!pqr=apquxz.ixr.zzz.ac.ukk No match /:/ Well, we need a colon: somewhere 0: : *** Fail if we don't No match /([\da-f:]+)$/i 0abc 0: 0abc abc 0: abc fed 0: fed E 0: E :: 0: :: 5f03:12C0::932e 0: 5f03:12C0::932e fed def 0: def Any old stuff 0: ff *** Failers No match 0zzz No match gzzz No match fed\x20 No match Any old rubbish No match /^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ .1.2.3 0: .1.2.3 A.12.123.0 0: A.12.123.0 *** Failers No match .1.2.3333 No match 1.2.3 No match 1234.2.3 No match /^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ 1 IN SOA non-sp1 non-sp2( 0: 1 IN SOA non-sp1 non-sp2( 1 IN SOA non-sp1 non-sp2 ( 0: 1 IN SOA non-sp1 non-sp2 ( *** Failers No match 1IN SOA non-sp1 non-sp2( No match /^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ a. 0: a. Z. 0: Z. 2. 0: 2. ab-c.pq-r. 0: ab-c.pq-r. sxk.zzz.ac.uk. 0: sxk.zzz.ac.uk. x-.y-. 0: x-.y-. *** Failers No match -abc.peq. No match /^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ *.a 0: *.a *.b0-a 0: *.b0-a *.c3-b.c 0: *.c3-b.c *.c-a.b-c 0: *.c-a.b-c *** Failers No match *.0 No match *.a- No match *.a-b.c- No match *.c-a.0-c No match /^(?=ab(de))(abd)(e)/ abde 0: abde /^(?!(ab)de|x)(abd)(f)/ abdf 0: abdf /^(?=(ab(cd)))(ab)/ abcd 0: ab /^[\da-f](\.[\da-f])*$/i a.b.c.d 0: a.b.c.d A.B.C.D 0: A.B.C.D a.b.c.1.2.3.C 0: a.b.c.1.2.3.C /^\".*\"\s*(;.*)?$/ \"1234\" 0: "1234" \"abcd\" ; 0: "abcd" ; \"\" ; rhubarb 0: "" ; rhubarb *** Failers No match \"1234\" : things No match /^$/ \ 0: *** Failers No match / ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x ab c 0: ab c *** Failers No match abc No match ab cde No match /(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ ab c 0: ab c *** Failers No match abc No match ab cde No match /^ a\ b[c ]d $/x a bcd 0: a bcd a b d 0: a b d *** Failers No match abcd No match ab d No match /^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ abcdefhijklm 0: abcdefhijklm /^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ abcdefhijklm 0: abcdefhijklm /^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ a+ Z0+\x08\n\x1d\x12 0: a+ Z0+\x08\x0a\x1d\x12 /^[.^$|()*+?{,}]+/ .^\$(*+)|{?,?} 0: .^$(*+)|{?,?} 1: .^$(*+)|{?,? 2: .^$(*+)|{?, 3: .^$(*+)|{? 4: .^$(*+)|{ 5: .^$(*+)| 6: .^$(*+) 7: .^$(*+ 8: .^$(* 9: .^$( 10: .^$ 11: .^ 12: . /^a*\w/ z 0: z az 0: az 1: a aaaz 0: aaaz 1: aaa 2: aa 3: a a 0: a aa 0: aa 1: a aaaa 0: aaaa 1: aaa 2: aa 3: a a+ 0: a aa+ 0: aa 1: a /^a*?\w/ z 0: z az 0: az 1: a aaaz 0: aaaz 1: aaa 2: aa 3: a a 0: a aa 0: aa 1: a aaaa 0: aaaa 1: aaa 2: aa 3: a a+ 0: a aa+ 0: aa 1: a /^a+\w/ az 0: az aaaz 0: aaaz 1: aaa 2: aa aa 0: aa aaaa 0: aaaa 1: aaa 2: aa aa+ 0: aa /^a+?\w/ az 0: az aaaz 0: aaaz 1: aaa 2: aa aa 0: aa aaaa 0: aaaa 1: aaa 2: aa aa+ 0: aa /^\d{8}\w{2,}/ 1234567890 0: 1234567890 12345678ab 0: 12345678ab 12345678__ 0: 12345678__ *** Failers No match 1234567 No match /^[aeiou\d]{4,5}$/ uoie 0: uoie 1234 0: 1234 12345 0: 12345 aaaaa 0: aaaaa *** Failers No match 123456 No match /^[aeiou\d]{4,5}?/ uoie 0: uoie 1234 0: 1234 12345 0: 12345 1: 1234 aaaaa 0: aaaaa 1: aaaa 123456 0: 12345 1: 1234 /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ From abcd Mon Sep 01 12:33:02 1997 0: From abcd Mon Sep 01 12:33 /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ From abcd Mon Sep 01 12:33:02 1997 0: From abcd Mon Sep 01 12:33 From abcd Mon Sep 1 12:33:02 1997 0: From abcd Mon Sep 1 12:33 *** Failers No match From abcd Sep 01 12:33:02 1997 No match /^12.34/s 12\n34 0: 12\x0a34 12\r34 0: 12\x0d34 /\w+(?=\t)/ the quick brown\t fox 0: brown /foo(?!bar)(.*)/ foobar is foolish see? 0: foolish see? 1: foolish see 2: foolish se 3: foolish s 4: foolish 5: foolish 6: foolis 7: fooli 8: fool 9: foo /(?:(?!foo)...|^.{0,2})bar(.*)/ foobar crowbar etc 0: rowbar etc 1: rowbar et 2: rowbar e 3: rowbar 4: rowbar barrel 0: barrel 1: barre 2: barr 3: bar 2barrel 0: 2barrel 1: 2barre 2: 2barr 3: 2bar A barrel 0: A barrel 1: A barre 2: A barr 3: A bar /^(\D*)(?=\d)(?!123)/ abc456 0: abc *** Failers No match abc123 No match /^1234(?# test newlines inside)/ 1234 0: 1234 /^1234 #comment in extended re /x 1234 0: 1234 /#rhubarb abcd/x abcd 0: abcd /^abcd#rhubarb/x abcd 0: abcd /(?!^)abc/ the abc 0: abc *** Failers No match abc No match /(?=^)abc/ abc 0: abc *** Failers No match the abc No match /^[ab]{1,3}(ab*|b)/ aabbbbb 0: aabbbbb 1: aabbbb 2: aabbb 3: aabb 4: aab 5: aa /^[ab]{1,3}?(ab*|b)/ aabbbbb 0: aabbbbb 1: aabbbb 2: aabbb 3: aabb 4: aab 5: aa /^[ab]{1,3}?(ab*?|b)/ aabbbbb 0: aabbbbb 1: aabbbb 2: aabbb 3: aabb 4: aab 5: aa /^[ab]{1,3}(ab*?|b)/ aabbbbb 0: aabbbbb 1: aabbbb 2: aabbb 3: aabb 4: aab 5: aa / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /x Alan Other 0: Alan Other 0: user@dom.ain 1: user@dom user\@dom.ain 0: user@dom.ain 1: user@dom \"A. Other\" (a comment) 0: "A. Other" (a comment) 1: "A. Other" 2: "A. Other" A. Other (a comment) 0: Other (a comment) 1: Other 2: Other \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) # leading word [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces (?: (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) | " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " ) # "special" comment or quoted string [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" )* < [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # < (?: @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* (?: , [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* )* # additional domains : [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address spec > # > # name and address ) /x Alan Other 0: Alan Other 0: user@dom.ain 1: user@dom user\@dom.ain 0: user@dom.ain 1: user@dom \"A. Other\" (a comment) 0: "A. Other" A. Other (a comment) 0: Other \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re A missing angle a\rb 0: a\x0db *** Failers No match a\nb No match /abc$/ abc 0: abc abc\n 0: abc *** Failers No match abc\ndef No match /(abc)\123/ abc\x53 0: abcS /(abc)\223/ abc\x93 0: abc\x93 /(abc)\323/ abc\xd3 0: abc\xd3 /(abc)\100/ abc\x40 0: abc@ abc\100 0: abc@ /(abc)\1000/ abc\x400 0: abc@0 abc\x40\x30 0: abc@0 abc\1000 0: abc@0 abc\100\x30 0: abc@0 abc\100\060 0: abc@0 abc\100\60 0: abc@0 /abc\81/ abc\081 0: abc\x0081 abc\0\x38\x31 0: abc\x0081 /abc\91/ abc\091 0: abc\x0091 abc\0\x39\x31 0: abc\x0091 /(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ abcdefghijk\12S 0: abcdefghijk\x0aS /ab\idef/ abidef 0: abidef /a{0}bc/ bc 0: bc /(a|(bc)){0,0}?xyz/ xyz 0: xyz /abc[\10]de/ abc\010de 0: abc\x08de /abc[\1]de/ abc\1de 0: abc\x01de /(abc)[\1]de/ abc\1de 0: abc\x01de /(?s)a.b/ a\nb 0: a\x0ab /^([^a])([^\b])([^c]*)([^d]{3,4})/ baNOTccccd 0: baNOTcccc 1: baNOTccc 2: baNOTcc 3: baNOTc 4: baNOT baNOTcccd 0: baNOTccc 1: baNOTcc 2: baNOTc 3: baNOT baNOTccd 0: baNOTcc 1: baNOTc 2: baNOT bacccd 0: baccc *** Failers 0: *** Failers 1: *** Failer 2: *** Faile 3: *** Fail 4: *** Fai 5: *** Fa 6: *** F anything No match b\bc No match baccd No match /[^a]/ Abc 0: A /[^a]/i Abc 0: b /[^a]+/ AAAaAbc 0: AAA 1: AA 2: A /[^a]+/i AAAaAbc 0: bc 1: b /[^a]+/ bbb\nccc 0: bbb\x0accc 1: bbb\x0acc 2: bbb\x0ac 3: bbb\x0a 4: bbb 5: bb 6: b /[^k]$/ abc 0: c *** Failers 0: s abk No match /[^k]{2,3}$/ abc 0: abc kbc 0: bc kabc 0: abc *** Failers 0: ers abk No match akb No match akk No match /^\d{8,}\@.+[^k]$/ 12345678\@a.b.c.d 0: 12345678@a.b.c.d 123456789\@x.y.z 0: 123456789@x.y.z *** Failers No match 12345678\@x.y.uk No match 1234567\@a.b.c.d No match /[^a]/ aaaabcd 0: b aaAabcd 0: A /[^a]/i aaaabcd 0: b aaAabcd 0: b /[^az]/ aaaabcd 0: b aaAabcd 0: A /[^az]/i aaaabcd 0: b aaAabcd 0: b /\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 0: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff /P[^*]TAIRE[^*]{1,6}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx 0: PSTAIREISLL /P[^*]TAIRE[^*]{1,}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx 0: PSTAIREISLL /(\.\d\d[1-9]?)\d+/ 1.230003938 0: .230003938 1: .23000393 2: .2300039 3: .230003 4: .23000 5: .2300 6: .230 1.875000282 0: .875000282 1: .87500028 2: .8750002 3: .875000 4: .87500 5: .8750 6: .875 1.235 0: .235 /(\.\d\d((?=0)|\d(?=\d)))/ 1.230003938 0: .230 1: .23 1.875000282 0: .875 *** Failers No match 1.235 No match /a(?)b/ ab 0: ab /\b(foo)\s+(\w+)/i Food is on the foo table 0: foo table 1: foo tabl 2: foo tab 3: foo ta 4: foo t /foo(.*)bar/ The food is under the bar in the barn. 0: food is under the bar in the bar 1: food is under the bar /foo(.*?)bar/ The food is under the bar in the barn. 0: food is under the bar in the bar 1: food is under the bar /(.*)(\d*)/ I have 2 numbers: 53147 Matched, but too many subsidiary matches 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: I have 2 numbers: 531 3: I have 2 numbers: 53 4: I have 2 numbers: 5 5: I have 2 numbers: 6: I have 2 numbers: 7: I have 2 numbers 8: I have 2 number 9: I have 2 numbe 10: I have 2 numb 11: I have 2 num 12: I have 2 nu 13: I have 2 n 14: I have 2 15: I have 2 16: I have 17: I have 18: I hav 19: I ha 20: I h 21: I /(.*)(\d+)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: I have 2 numbers: 531 3: I have 2 numbers: 53 4: I have 2 numbers: 5 5: I have 2 /(.*?)(\d*)/ I have 2 numbers: 53147 Matched, but too many subsidiary matches 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: I have 2 numbers: 531 3: I have 2 numbers: 53 4: I have 2 numbers: 5 5: I have 2 numbers: 6: I have 2 numbers: 7: I have 2 numbers 8: I have 2 number 9: I have 2 numbe 10: I have 2 numb 11: I have 2 num 12: I have 2 nu 13: I have 2 n 14: I have 2 15: I have 2 16: I have 17: I have 18: I hav 19: I ha 20: I h 21: I /(.*?)(\d+)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: I have 2 numbers: 531 3: I have 2 numbers: 53 4: I have 2 numbers: 5 5: I have 2 /(.*)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 /(.*?)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 /(.*)\b(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 /(.*\D)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 /^\D*(?!123)/ ABC123 0: AB 1: A 2: /^(\D*)(?=\d)(?!123)/ ABC445 0: ABC *** Failers No match ABC123 No match /^[W-]46]/ W46]789 0: W46] -46]789 0: -46] *** Failers No match Wall No match Zebra No match 42 No match [abcd] No match ]abcd[ No match /^[W-\]46]/ W46]789 0: W Wall 0: W Zebra 0: Z Xylophone 0: X 42 0: 4 [abcd] 0: [ ]abcd[ 0: ] \\backslash 0: \ *** Failers No match -46]789 No match well No match /\d\d\/\d\d\/\d\d\d\d/ 01/01/2000 0: 01/01/2000 /word (?:[a-zA-Z0-9]+ ){0,10}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark No match /word (?:[a-zA-Z0-9]+ ){0,300}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match /^(a){0,0}/ bcd 0: abc 0: aab 0: /^(a){0,1}/ bcd 0: abc 0: a 1: aab 0: a 1: /^(a){0,2}/ bcd 0: abc 0: a 1: aab 0: aa 1: a 2: /^(a){0,3}/ bcd 0: abc 0: a 1: aab 0: aa 1: a 2: aaa 0: aaa 1: aa 2: a 3: /^(a){0,}/ bcd 0: abc 0: a 1: aab 0: aa 1: a 2: aaa 0: aaa 1: aa 2: a 3: aaaaaaaa 0: aaaaaaaa 1: aaaaaaa 2: aaaaaa 3: aaaaa 4: aaaa 5: aaa 6: aa 7: a 8: /^(a){1,1}/ bcd No match abc 0: a aab 0: a /^(a){1,2}/ bcd No match abc 0: a aab 0: aa 1: a /^(a){1,3}/ bcd No match abc 0: a aab 0: aa 1: a aaa 0: aaa 1: aa 2: a /^(a){1,}/ bcd No match abc 0: a aab 0: aa 1: a aaa 0: aaa 1: aa 2: a aaaaaaaa 0: aaaaaaaa 1: aaaaaaa 2: aaaaaa 3: aaaaa 4: aaaa 5: aaa 6: aa 7: a /.*\.gif/ borfle\nbib.gif\nno 0: bib.gif /.{0,}\.gif/ borfle\nbib.gif\nno 0: bib.gif /.*\.gif/m borfle\nbib.gif\nno 0: bib.gif /.*\.gif/s borfle\nbib.gif\nno 0: borfle\x0abib.gif /.*\.gif/ms borfle\nbib.gif\nno 0: borfle\x0abib.gif /.*$/ borfle\nbib.gif\nno 0: no /.*$/m borfle\nbib.gif\nno 0: borfle /.*$/s borfle\nbib.gif\nno 0: borfle\x0abib.gif\x0ano /.*$/ms borfle\nbib.gif\nno 0: borfle\x0abib.gif\x0ano 1: borfle\x0abib.gif 2: borfle /.*$/ borfle\nbib.gif\nno\n 0: no /.*$/m borfle\nbib.gif\nno\n 0: borfle /.*$/s borfle\nbib.gif\nno\n 0: borfle\x0abib.gif\x0ano\x0a 1: borfle\x0abib.gif\x0ano /.*$/ms borfle\nbib.gif\nno\n 0: borfle\x0abib.gif\x0ano\x0a 1: borfle\x0abib.gif\x0ano 2: borfle\x0abib.gif 3: borfle /(.*X|^B)/ abcde\n1234Xyz 0: 1234X BarFoo 0: B *** Failers No match abcde\nBar No match /(.*X|^B)/m abcde\n1234Xyz 0: 1234X BarFoo 0: B abcde\nBar 0: B /(.*X|^B)/s abcde\n1234Xyz 0: abcde\x0a1234X BarFoo 0: B *** Failers No match abcde\nBar No match /(.*X|^B)/ms abcde\n1234Xyz 0: abcde\x0a1234X BarFoo 0: B abcde\nBar 0: B /(?s)(.*X|^B)/ abcde\n1234Xyz 0: abcde\x0a1234X BarFoo 0: B *** Failers No match abcde\nBar No match /(?s:.*X|^B)/ abcde\n1234Xyz 0: abcde\x0a1234X BarFoo 0: B *** Failers No match abcde\nBar No match /^.*B/ **** Failers No match abc\nB No match /(?s)^.*B/ abc\nB 0: abc\x0aB /(?m)^.*B/ abc\nB 0: B /(?ms)^.*B/ abc\nB 0: abc\x0aB /(?ms)^B/ abc\nB 0: B /(?s)B$/ B\n 0: B /^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ 123456654321 0: 123456654321 /^\d\d\d\d\d\d\d\d\d\d\d\d/ 123456654321 0: 123456654321 /^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ 123456654321 0: 123456654321 /^[abc]{12}/ abcabcabcabc 0: abcabcabcabc /^[a-c]{12}/ abcabcabcabc 0: abcabcabcabc /^(a|b|c){12}/ abcabcabcabc 0: abcabcabcabc /^[abcdefghijklmnopqrstuvwxy0123456789]/ n 0: n *** Failers No match z No match /abcde{0,0}/ abcd 0: abcd *** Failers No match abce No match /ab[cd]{0,0}e/ abe 0: abe *** Failers No match abcde No match /ab(c){0,0}d/ abd 0: abd *** Failers No match abcd No match /a(b*)/ a 0: a ab 0: ab 1: a abbbb 0: abbbb 1: abbb 2: abb 3: ab 4: a *** Failers 0: a bbbbb No match /ab\d{0}e/ abe 0: abe *** Failers No match ab1e No match /"([^\\"]+|\\.)*"/ the \"quick\" brown fox 0: "quick" \"the \\\"quick\\\" brown fox\" 0: "the \"quick\" brown fox" /.*?/g+ abc 0: abc 0+ 1: ab 2: a 3: 0: 0+ /\b/g+ abc 0: 0+ abc 0: 0+ /\b/+g abc 0: 0+ abc 0: 0+ //g abc 0: 0: 0: 0: /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is 43.
Word Processor
(N-1286)
Lega lstaff.comCA - Statewide 0: 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide /a[^a]b/ acb 0: acb a\nb 0: a\x0ab /a.b/ acb 0: acb *** Failers No match a\nb No match /a[^a]b/s acb 0: acb a\nb 0: a\x0ab /a.b/s acb 0: acb a\nb 0: a\x0ab /^(b+?|a){1,2}?c/ bac 0: bac bbac 0: bbac bbbac 0: bbbac bbbbac 0: bbbbac bbbbbac 0: bbbbbac /^(b+|a){1,2}?c/ bac 0: bac bbac 0: bbac bbbac 0: bbbac bbbbac 0: bbbbac bbbbbac 0: bbbbbac /(?!\A)x/m x\nb\n No match a\bx\n 0: x /\x0{ab}/ \0{ab} 0: \x00{ab} /(A|B)*?CD/ CD 0: CD /(A|B)*CD/ CD 0: CD /(?.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ No match "(?>.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo /(?>(\.\d\d[1-9]?))\d+/ 1.230003938 0: .230003938 1: .23000393 2: .2300039 3: .230003 4: .23000 5: .2300 6: .230 1.875000282 0: .875000282 1: .87500028 2: .8750002 3: .875000 4: .87500 5: .8750 *** Failers No match 1.235 No match /^((?>\w+)|(?>\s+))*$/ now is the time for all good men to come to the aid of the party 0: now is the time for all good men to come to the aid of the party *** Failers No match this is not a line with only words and spaces! No match /(\d+)(\w)/ 12345a 0: 12345a 1: 12345 2: 1234 3: 123 4: 12 12345+ 0: 12345 1: 1234 2: 123 3: 12 /((?>\d+))(\w)/ 12345a 0: 12345a *** Failers No match 12345+ No match /(?>a+)b/ aaab 0: aaab /((?>a+)b)/ aaab 0: aaab /(?>(a+))b/ aaab 0: aaab /(?>b)+/ aaabbbccc 0: bbb 1: bb 2: b /(?>a+|b+|c+)*c/ aaabbbbccccd 0: aaabbbbcccc 1: aaabbbbc /(a+|b+|c+)*c/ aaabbbbccccd 0: aaabbbbcccc 1: aaabbbbccc 2: aaabbbbcc 3: aaabbbbc /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: abc(ade)ufh()() 2: abc(ade)ufh() 3: abc(ade)ufh 4: abc(ade) 5: abc /\(((?>[^()]+)|\([^()]+\))+\)/ (abc) 0: (abc) (abc(def)xyz) 0: (abc(def)xyz) *** Failers No match ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /a(?-i)b/i ab 0: ab Ab 0: Ab *** Failers No match aB No match AB No match /(a (?x)b c)d e/ a bcd e 0: a bcd e *** Failers No match a b cd e No match abcd e No match a bcde No match /(a b(?x)c d (?-x)e f)/ a bcde f 0: a bcde f *** Failers No match abcdef No match /(a(?i)b)c/ abc 0: abc aBc 0: aBc *** Failers No match abC No match aBC No match Abc No match ABc No match ABC No match AbC No match /a(?i:b)c/ abc 0: abc aBc 0: aBc *** Failers No match ABC No match abC No match aBC No match /a(?i:b)*c/ aBc 0: aBc aBBc 0: aBBc *** Failers No match aBC No match aBBC No match /a(?=b(?i)c)\w\wd/ abcd 0: abcd abCd 0: abCd *** Failers No match aBCd No match abcD No match /(?s-i:more.*than).*million/i more than million 0: more than million more than MILLION 0: more than MILLION more \n than Million 0: more \x0a than Million *** Failers No match MORE THAN MILLION No match more \n than \n million No match /(?:(?s-i)more.*than).*million/i more than million 0: more than million more than MILLION 0: more than MILLION more \n than Million 0: more \x0a than Million *** Failers No match MORE THAN MILLION No match more \n than \n million No match /(?>a(?i)b+)+c/ abc 0: abc aBbc 0: aBbc aBBc 0: aBBc *** Failers No match Abc No match abAb No match abbC No match /(?=a(?i)b)\w\wc/ abc 0: abc aBc 0: aBc *** Failers No match Ab No match abC No match aBC No match /(?<=a(?i)b)(\w\w)c/ abxxc 0: xxc aBxxc 0: xxc *** Failers No match Abxxc No match ABxxc No match abxxC No match /^(?(?=abc)\w{3}:|\d\d)$/ abc: 0: abc: 12 0: 12 *** Failers No match 123 No match xyz No match /^(?(?!abc)\d\d|\w{3}:)$/ abc: 0: abc: 12 0: 12 *** Failers No match 123 No match xyz No match /(?(?<=foo)bar|cat)/ foobar 0: bar cat 0: cat fcat 0: cat focat 0: cat *** Failers No match foocat No match /(?(?a*)*/ a 0: a 1: aa 0: aa 1: aaaa 0: aaaa 1: /(abc|)+/ abc 0: abc 1: abcabc 0: abcabc 1: abc 2: abcabcabc 0: abcabcabc 1: abcabc 2: abc 3: xyz 0: /([a]*)*/ a 0: a 1: aaaaa 0: aaaaa 1: aaaa 2: aaa 3: aa 4: a 5: /([ab]*)*/ a 0: a 1: b 0: b 1: ababab 0: ababab 1: ababa 2: abab 3: aba 4: ab 5: a 6: aaaabcde 0: aaaab 1: aaaa 2: aaa 3: aa 4: a 5: bbbb 0: bbbb 1: bbb 2: bb 3: b 4: /([^a]*)*/ b 0: b 1: bbbb 0: bbbb 1: bbb 2: bb 3: b 4: aaa 0: /([^ab]*)*/ cccc 0: cccc 1: ccc 2: cc 3: c 4: abab 0: /([a]*?)*/ a 0: a 1: aaaa 0: aaaa 1: aaa 2: aa 3: a 4: /([ab]*?)*/ a 0: a 1: b 0: b 1: abab 0: abab 1: aba 2: ab 3: a 4: baba 0: baba 1: bab 2: ba 3: b 4: /([^a]*?)*/ b 0: b 1: bbbb 0: bbbb 1: bbb 2: bb 3: b 4: aaa 0: /([^ab]*?)*/ c 0: c 1: cccc 0: cccc 1: ccc 2: cc 3: c 4: baba 0: /(?>a*)*/ a 0: a 1: aaabcde 0: aaa 1: /((?>a*))*/ aaaaa 0: aaaaa 1: aabbaa 0: aa 1: /((?>a*?))*/ aaaaa 0: aaaaa 1: aabbaa 0: aa 1: /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x 12-sep-98 0: 12-sep-98 12-09-98 0: 12-09-98 *** Failers No match sep-12-98 No match /(?i:saturday|sunday)/ saturday 0: saturday sunday 0: sunday Saturday 0: Saturday Sunday 0: Sunday SATURDAY 0: SATURDAY SUNDAY 0: SUNDAY SunDay 0: SunDay /(a(?i)bc|BB)x/ abcx 0: abcx aBCx 0: aBCx bbx 0: bbx BBx 0: BBx *** Failers No match abcX No match aBCX No match bbX No match BBX No match /^([ab](?i)[cd]|[ef])/ ac 0: ac aC 0: aC bD 0: bD elephant 0: e Europe 0: E frog 0: f France 0: F *** Failers No match Africa No match /^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ ab 0: ab aBd 0: aBd xy 0: xy xY 0: xY zebra 0: z Zambesi 0: Z *** Failers No match aCD No match XY No match /(?<=foo\n)^bar/m foo\nbar 0: bar *** Failers No match bar No match baz\nbar No match /(?<=(?]&/ <&OUT 0: <& /(?:(f)(o)(o)|(b)(a)(r))*/ foobar 0: foobar 1: foo 2: /(?<=a)b/ ab 0: b *** Failers No match cb No match b No match /(?a+)ab/ /(?>a+)b/ aaab 0: aaab /([[:]+)/ a:[b]: 0: :[ 1: : /([[=]+)/ a=[b]= 0: =[ 1: = /([[.]+)/ a.[b]. 0: .[ 1: . /((?>a+)b)/ aaab 0: aaab /(?>(a+))b/ aaab 0: aaab /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: abc(ade)ufh()() 2: abc(ade)ufh() 3: abc(ade)ufh 4: abc(ade) 5: abc /a\Z/ *** Failers No match aaab No match a\nb\n No match /b\Z/ a\nb\n 0: b /b\z/ /b\Z/ a\nb 0: b /b\z/ a\nb 0: b *** Failers No match /(?>.*)(?<=(abcd|wxyz))/ alphabetabcd 0: alphabetabcd endingwxyz 0: endingwxyz *** Failers No match a rather long string that doesn't end with one of them No match /word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark No match /word (?>[a-zA-Z0-9]+ ){0,30}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match /(?<=\d{3}(?!999))foo/ 999foo 0: foo 123999foo 0: foo *** Failers No match 123abcfoo No match /(?<=(?!...999)\d{3})foo/ 999foo 0: foo 123999foo 0: foo *** Failers No match 123abcfoo No match /(?<=\d{3}(?!999)...)foo/ 123abcfoo 0: foo 123456foo 0: foo *** Failers No match 123999foo No match /(?<=\d{3}...)(?Z)+|A)*/ ZABCDEFG 0: ZA 1: Z 2: /((?>)+|A)*/ ZABCDEFG 0: /a*/g abbab 0: a 1: 0: 0: 0: a 1: 0: 0: /^[a-\d]/ abcde 0: a -things 0: - 0digit 0: 0 *** Failers No match bcdef No match /^[\d-a]/ abcde 0: a -things 0: - 0digit 0: 0 *** Failers No match bcdef No match /[[:space:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d\x0b 1: \x09\x0a\x0c\x0d 2: \x09\x0a\x0c 3: \x09\x0a 4: \x09 5: /[[:blank:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09 1: /[\s]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d 1: \x09\x0a\x0c 2: \x09\x0a 3: \x09 4: /\s+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d 1: \x09\x0a\x0c 2: \x09\x0a 3: \x09 4: /a b/x ab No match /(?!\A)x/m a\nxb\n 0: x /(?!^)x/m a\nxb\n No match /abc\Qabc\Eabc/ abcabcabc 0: abcabcabc /abc\Q(*+|\Eabc/ abc(*+|abc 0: abc(*+|abc / abc\Q abc\Eabc/x abc abcabc 0: abc abcabc *** Failers No match abcabcabc No match /abc#comment \Q#not comment literal\E/x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal/x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal\E #more comment /x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal\E #more comment/x abc#not comment\n literal 0: abc#not comment\x0a literal /\Qabc\$xyz\E/ abc\\\$xyz 0: abc\$xyz /\Qabc\E\$\Qxyz\E/ abc\$xyz 0: abc$xyz /\Gabc/ abc 0: abc *** Failers No match xyzabc No match /\Gabc./g abc1abc2xyzabc3 0: abc1 0: abc2 /abc./g abc1abc2xyzabc3 0: abc1 0: abc2 0: abc3 /a(?x: b c )d/ XabcdY 0: abcd *** Failers No match Xa b c d Y No match /((?x)x y z | a b c)/ XabcY 0: abc AxyzB 0: xyz /(?i)AB(?-i)C/ XabCY 0: abC *** Failers No match XabcY No match /((?i)AB(?-i)C|D)E/ abCE 0: abCE DE 0: DE *** Failers No match abcE No match abCe No match dE No match De No match /[z\Qa-d]\E]/ z 0: z a 0: a - 0: - d 0: d ] 0: ] *** Failers 0: a b No match /[\z\C]/ z 0: z C 0: C /\M/ M 0: M /(a+)*b/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /(?i)reg(?:ul(?:[aä]|ae)r|ex)/ REGular 0: REGular regulaer 0: regulaer Regex 0: Regex regulär 0: regul\xe4r /Åæåä[à-ÿÀ-ß]+/ Åæåäà 0: \xc5\xe6\xe5\xe4\xe0 Åæåäÿ 0: \xc5\xe6\xe5\xe4\xff ÅæåäÀ 0: \xc5\xe6\xe5\xe4\xc0 Åæåäß 0: \xc5\xe6\xe5\xe4\xdf /(?<=Z)X./ \x84XAZXB 0: XB /^(?(2)a|(1)(2))+$/ 123a Error -17 (backreference condition or recursion test not supported for DFA matching) /(?<=a|bbbb)c/ ac 0: c bbbbc 0: c /abc/SS>testsavedregex Compiled pattern written to testsavedregex testsavedregex Compiled pattern written to testsavedregex testsavedregex Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex Compiled pattern written to testsavedregex Study data written to testsavedregex 0: abc xyz\r\nabc\ 0: abc xyz\rabc\ 0: abc xyz\r\nabc\ 0: abc ** Failers No match xyz\nabc\ No match xyz\r\nabc\ No match xyz\nabc\ No match xyz\rabc\ No match xyz\rabc\ No match /abc$/m xyzabc 0: abc xyzabc\n 0: abc xyzabc\npqr 0: abc xyzabc\r\ 0: abc xyzabc\rpqr\ 0: abc xyzabc\r\n\ 0: abc xyzabc\r\npqr\ 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 xyz\rabcdef 0: abc xyz\nabcdef\ 0: abc ** Failers No match xyz\nabcdef No match /^abc/m xyz\nabcdef 0: abc xyz\rabcdef\ 0: abc ** Failers No match xyz\rabcdef No match /^abc/m xyz\r\nabcdef 0: abc xyz\rabcdef\ 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: \abc\ndef 0: abc\x0adef 1: abc\x0ade 2: abc\x0ad 3: abc\x0a 4: abc 5: ab 6: a 7: \abc\rdef 0: abc 1: ab 2: a 3: \abc\r\ndef 0: abc 1: ab 2: a 3: \abc\ndef 0: abc\x0adef 1: abc\x0ade 2: abc\x0ad 3: abc\x0a 4: abc 5: ab 6: a 7: \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 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 /^\w+=.*(\\\n.*)*/ abc=xyz\\\npqr 0: abc=xyz\\x0apqr 1: abc=xyz\\x0apq 2: abc=xyz\\x0ap 3: abc=xyz\\x0a 4: abc=xyz\ 5: abc=xyz 6: abc=xy 7: abc=x 8: abc= /^(a()*)*/ aaaa 0: aaaa 1: aaa 2: aa 3: a 4: /^(?:a(?:(?:))*)*/ aaaa 0: aaaa 1: aaa 2: aa 3: a 4: /^(a()+)+/ aaaa 0: aaaa 1: aaa 2: aa 3: a /^(?:a(?:(?:))+)+/ aaaa 0: aaaa 1: aaa 2: aa 3: a /(a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /(?>a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /(?:a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /^a.b/ a\rb 0: a\x0db a\nb\ 0: a\x0ab ** Failers No match a\nb No match a\nb\ No match a\rb\ No match a\rb\ No match /^abc./mgx abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc7 /abc.$/mgx abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc9 /^a\Rb/ a\nb 0: a\x0ab a\rb 0: a\x0db a\r\nb 0: a\x0d\x0ab a\x0bb 0: a\x0bb a\x0cb 0: a\x0cb a\x85b 0: a\x85b ** Failers No match a\n\rb No match /^a\R*b/ ab 0: ab a\nb 0: a\x0ab a\rb 0: a\x0db a\r\nb 0: a\x0d\x0ab a\x0bb 0: a\x0bb a\x0cb 0: a\x0cb a\x85b 0: a\x85b a\n\rb 0: a\x0a\x0db a\n\r\x85\x0cb 0: a\x0a\x0d\x85\x0cb /^a\R+b/ a\nb 0: a\x0ab a\rb 0: a\x0db a\r\nb 0: a\x0d\x0ab a\x0bb 0: a\x0bb a\x0cb 0: a\x0cb a\x85b 0: a\x85b a\n\rb 0: a\x0a\x0db a\n\r\x85\x0cb 0: a\x0a\x0d\x85\x0cb ** Failers No match ab No match /^a\R{1,3}b/ a\nb 0: a\x0ab a\n\rb 0: a\x0a\x0db a\n\r\x85b 0: a\x0a\x0d\x85b a\r\n\r\nb 0: a\x0d\x0a\x0d\x0ab a\r\n\r\n\r\nb 0: a\x0d\x0a\x0d\x0a\x0d\x0ab a\n\r\n\rb 0: a\x0a\x0d\x0a\x0db a\n\n\r\nb 0: a\x0a\x0a\x0d\x0ab ** Failers No match a\n\n\n\rb No match a\r No match /^a[\R]b/ aRb 0: aRb ** Failers No match a\nb No match /.+foo/ afoo 0: afoo ** Failers No match \r\nfoo No match \nfoo No match /.+foo/ afoo 0: afoo \nfoo 0: \x0afoo ** Failers No match \r\nfoo No match /.+foo/ afoo 0: afoo ** Failers No match \nfoo No match \r\nfoo No match /.+foo/s afoo 0: afoo \r\nfoo 0: \x0d\x0afoo \nfoo 0: \x0afoo /^$/mg abc\r\rxyz 0: abc\n\rxyz 0: ** Failers No match abc\r\nxyz No match /^X/m XABC 0: X ** Failers No match XABC\B No match /(?m)^$/g+ abc\r\n\r\n 0: 0+ \x0d\x0a /(?m)^$|^\r\n/g+ abc\r\n\r\n 0: \x0d\x0a 0+ 1: /(?m)$/g+ abc\r\n\r\n 0: 0+ \x0d\x0a\x0d\x0a 0: 0+ \x0d\x0a 0: 0+ /(?|(abc)|(xyz))/ >abc< 0: abc >xyz< 0: xyz /(x)(?|(abc)|(xyz))(x)/ xabcx 0: xabcx xxyzx 0: xxyzx /(x)(?|(abc)(pqr)|(xyz))(x)/ xabcpqrx 0: xabcpqrx xxyzx 0: xxyzx /(?|(abc)|(xyz))(?1)/ abcabc 0: abcabc xyzabc 0: xyzabc ** Failers No match xyzxyz No match /\H\h\V\v/ X X\x0a 0: X X\x0a X\x09X\x0b 0: X\x09X\x0b ** Failers No match \xa0 X\x0a No match /\H*\h+\V?\v{3,4}/ \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a 0: \x09 \xa0X\x0a\x0b\x0c\x0d 1: \x09 \xa0X\x0a\x0b\x0c \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a 0: \x09 \xa0\x0a\x0b\x0c\x0d 1: \x09 \xa0\x0a\x0b\x0c \x09\x20\xa0\x0a\x0b\x0c 0: \x09 \xa0\x0a\x0b\x0c ** Failers No match \x09\x20\xa0\x0a\x0b No match /\H{3,4}/ XY ABCDE 0: ABCD 1: ABC XY PQR ST 0: PQR /.\h{3,4}./ XY AB PQRS 0: B P 1: B /\h*X\h?\H+Y\H?Z/ >XNNNYZ 0: XNNNYZ > X NYQZ 0: X NYQZ ** Failers No match >XYZ No match > X NY Z No match /\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ >XY\x0aZ\x0aA\x0bNN\x0c 0: XY\x0aZ\x0aA\x0bNN\x0c >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c /.+A/ \r\nA No match /\nA/ \r\nA 0: \x0aA /[\r\n]A/ \r\nA 0: \x0aA /(\r|\n)A/ \r\nA 0: \x0aA /a\Rb/I Capturing subpattern count = 0 Options: bsr_anycrlf First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab ** Failers No match a\x85b No match a\x0bb No match /a\Rb/I Capturing subpattern count = 0 Options: bsr_unicode First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab a\x85b 0: a\x85b a\x0bb 0: a\x0bb ** Failers No match a\x85b\ No match a\x0bb\ No match /a\R?b/I Capturing subpattern count = 0 Options: bsr_anycrlf First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab ** Failers No match a\x85b No match a\x0bb No match /a\R?b/I Capturing subpattern count = 0 Options: bsr_unicode First char = 'a' Need char = 'b' a\rb 0: a\x0db a\nb 0: a\x0ab a\r\nb 0: a\x0d\x0ab a\x85b 0: a\x85b a\x0bb 0: a\x0bb ** Failers No match a\x85b\ No match a\x0bb\ No match /a\R{2,4}b/I Capturing subpattern count = 0 Options: bsr_anycrlf First char = 'a' Need char = 'b' a\r\n\nb 0: a\x0d\x0a\x0ab a\n\r\rb 0: a\x0a\x0d\x0db a\r\n\r\n\r\n\r\nb 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab ** Failers No match a\x85\85b No match a\x0b\0bb No match /a\R{2,4}b/I Capturing subpattern count = 0 Options: bsr_unicode First char = 'a' Need char = 'b' a\r\rb 0: a\x0d\x0db a\n\n\nb 0: a\x0a\x0a\x0ab a\r\n\n\r\rb 0: a\x0d\x0a\x0a\x0d\x0db a\x85\85b No match a\x0b\0bb No match ** Failers No match a\r\r\r\r\rb No match a\x85\85b\ No match a\x0b\0bb\ No match /a(?!)|\wbc/ abc 0: abc /a[]b/ ** Failers No match ab No match /a[]+b/ ** Failers No match ab No match /a[]*+b/ ** Failers No match ab No match /a[^]b/ aXb 0: aXb a\nb 0: a\x0ab ** Failers No match ab No match /a[^]+b/ aXb 0: aXb a\nX\nXb 0: a\x0aX\x0aXb ** Failers No match ab No match /X$/E X 0: X ** Failers No match X\n No match /X$/ X 0: X X\n 0: X /xyz/C xyz --->xyz +0 ^ x +1 ^^ y +2 ^ ^ z +3 ^ ^ 0: xyz abcxyz --->abcxyz +0 ^ x +1 ^^ y +2 ^ ^ z +3 ^ ^ 0: xyz abcxyz\Y --->abcxyz +0 ^ x +0 ^ x +0 ^ x +0 ^ x +1 ^^ y +2 ^ ^ z +3 ^ ^ 0: xyz ** Failers No match abc No match abc\Y --->abc +0 ^ x +0 ^ x +0 ^ x +0 ^ x No match abcxypqr No match abcxypqr\Y --->abcxypqr +0 ^ x +0 ^ x +0 ^ x +0 ^ x +1 ^^ y +2 ^ ^ z +0 ^ x +0 ^ x +0 ^ x +0 ^ x +0 ^ x No match /(*NO_START_OPT)xyz/C abcxyz --->abcxyz +15 ^ x +15 ^ x +15 ^ x +15 ^ x +16 ^^ y +17 ^ ^ z +18 ^ ^ 0: xyz /(?C)ab/ ab --->ab 0 ^ a 0: ab \C-ab 0: ab /ab/C ab --->ab +0 ^ a +1 ^^ b +2 ^ ^ 0: ab \C-ab 0: ab /^"((?(?=[a])[^"])|b)*"$/C "ab" --->"ab" +0 ^ ^ +1 ^ " +2 ^^ ((?(?=[a])[^"])|b)* +21 ^^ " +3 ^^ (?(?=[a])[^"]) +18 ^^ b +5 ^^ (?=[a]) +8 ^ [a] +11 ^^ ) +12 ^^ [^"] +16 ^ ^ ) +17 ^ ^ | +21 ^ ^ " +3 ^ ^ (?(?=[a])[^"]) +18 ^ ^ b +5 ^ ^ (?=[a]) +8 ^ [a] +19 ^ ^ ) +21 ^ ^ " +3 ^ ^ (?(?=[a])[^"]) +18 ^ ^ b +5 ^ ^ (?=[a]) +8 ^ [a] +17 ^ ^ | +22 ^ ^ $ +23 ^ ^ 0: "ab" \C-"ab" 0: "ab" /\d+X|9+Y/ ++++123999\P Partial match: 123999 ++++123999Y\P 0: 999Y /Z(*F)/ Z\P No match ZA\P No match /Z(?!)/ Z\P No match ZA\P No match /dog(sbody)?/ dogs\P 0: dog dogs\P\P Partial match: dogs /dog(sbody)??/ dogs\P 0: dog dogs\P\P Partial match: dogs /dog|dogsbody/ dogs\P 0: dog dogs\P\P Partial match: dogs /dogsbody|dog/ dogs\P 0: dog dogs\P\P Partial match: dogs /Z(*F)Q|ZXY/ Z\P Partial match: Z ZA\P No match X\P No match /\bthe cat\b/ the cat\P 0: the cat the cat\P\P Partial match: the cat /dog(sbody)?/ dogs\D\P 0: dog body\D\R 0: body /dog(sbody)?/ dogs\D\P\P Partial match: dogs body\D\R 0: body /abc/ abc\P 0: abc abc\P\P 0: abc /abc\K123/ xyzabc123pqr Error -16 (item unsupported for DFA matching) /(?<=abc)123/ xyzabc123pqr 0: 123 xyzabc12\P Partial match: abc12 xyzabc12\P\P Partial match: abc12 /\babc\b/ +++abc+++ 0: abc +++ab\P Partial match: +ab +++ab\P\P Partial match: +ab /(?=C)/g+ ABCDECBA 0: 0+ CDECBA 0: 0+ CBA /(abc|def|xyz)/I Capturing subpattern count = 1 No options No first char No need char terhjk;abcdaadsfe 0: abc the quick xyz brown fox 0: xyz \Yterhjk;abcdaadsfe 0: abc \Ythe quick xyz brown fox 0: xyz ** Failers No match thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd No match \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd No match /(abc|def|xyz)/SI Capturing subpattern count = 1 No options No first char No need char Subject length lower bound = 3 Starting byte set: a d x terhjk;abcdaadsfe 0: abc the quick xyz brown fox 0: xyz \Yterhjk;abcdaadsfe 0: abc \Ythe quick xyz brown fox 0: xyz ** Failers No match thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd No match \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd No match /abcd*/+ xxxxabcd\P 0: abcd 0+ 1: abc xxxxabcd\P\P Partial match: abcd dddxxx\R 0: ddd 0+ xxx 1: dd 2: d 3: xxxxabcd\P\P Partial match: abcd xxx\R 0: 0+ xxx /abcd*/i xxxxabcd\P 0: abcd 1: abc xxxxabcd\P\P Partial match: abcd XXXXABCD\P 0: ABCD 1: ABC XXXXABCD\P\P Partial match: ABCD /abc\d*/ xxxxabc1\P 0: abc1 1: abc xxxxabc1\P\P Partial match: abc1 /abc[de]*/ xxxxabcde\P 0: abcde 1: abcd 2: abc xxxxabcde\P\P Partial match: abcde /(?:(?1)|B)(A(*F)|C)/ ABCD 0: BC CCD 0: CC ** Failers No match CAD No match /^(?:(?1)|B)(A(*F)|C)/ CCD 0: CC BCD 0: BC ** Failers No match ABCD No match CAD No match BAD No match /^(?!a(*SKIP)b)/ ac Error -16 (item unsupported for DFA matching) /^(?=a(*SKIP)b|ac)/ ** Failers No match ac Error -16 (item unsupported for DFA matching) /^(?=a(*THEN)b|ac)/ ac Error -16 (item unsupported for DFA matching) /^(?=a(*PRUNE)b)/ ab Error -16 (item unsupported for DFA matching) ** Failers No match ac Error -16 (item unsupported for DFA matching) /^(?(?!a(*SKIP)b))/ ac Error -16 (item unsupported for DFA matching) /(?<=abc)def/ abc\P\P Partial match: abc /abc$/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc$/m abc 0: abc abc\n 0: abc abc\P\P Partial match: abc abc\n\P\P 0: abc abc\P 0: abc abc\n\P 0: abc /abc\z/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc\Z/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc\b/ abc 0: abc abc\P 0: abc abc\P\P Partial match: abc /abc\B/ abc No match abc\P Partial match: abc abc\P\P Partial match: abc /.+/ abc\>0 0: abc 1: ab 2: a abc\>1 0: bc 1: b abc\>2 0: c abc\>3 No match abc\>4 Error -24 (bad offset value) abc\>-4 Error -24 (bad offset value) /^(?:a)++\w/ aaaab 0: aaaab ** Failers No match aaaa No match bbb No match /^(?:aa|(?:a)++\w)/ aaaab 0: aaaab 1: aa aaaa 0: aa ** Failers No match bbb No match /^(?:a)*+\w/ aaaab 0: aaaab bbb 0: b ** Failers No match aaaa No match /^(a)++\w/ aaaab 0: aaaab ** Failers No match aaaa No match bbb No match /^(a|)++\w/ aaaab 0: aaaab ** Failers No match aaaa No match bbb No match /(?=abc){3}abc/+ abcabcabc 0: abc 0+ abcabc ** Failers No match xyz No match /(?=abc)+abc/+ abcabcabc 0: abc 0+ abcabc ** Failers No match xyz No match /(?=abc)++abc/+ abcabcabc 0: abc 0+ abcabc ** Failers No match xyz No match /(?=abc){0}xyz/ xyz 0: xyz /(?=abc){1}xyz/ ** Failers No match xyz No match /(?=(a))?./ ab 0: a bc 0: b /(?=(a))??./ ab 0: a bc 0: b /^(?=(a)){0}b(?1)/ backgammon 0: ba /^(?=(?1))?[az]([abc])d/ abd 0: abd zcdxx 0: zcd /^(?!a){0}\w+/ aaaaa 0: aaaaa 1: aaaa 2: aaa 3: aa 4: a /(?<=(abc))?xyz/ abcxyz 0: xyz pqrxyz 0: xyz /((?2))((?1))/ abc Error -26 (nested recursion at the same subject position) /(?(R)a+|(?R)b)/ aaaabcde 0: aaaab /(?(R)a+|((?R))b)/ aaaabcde 0: aaaab /((?(R)a+|(?1)b))/ aaaabcde 0: aaaab /((?(R2)a+|(?1)b))/ aaaabcde Error -17 (backreference condition or recursion test not supported for DFA matching) /(?(R)a*(?1)|((?R))b)/ aaaabcde Error -26 (nested recursion at the same subject position) /(a+)/ \O6aaaa Matched, but too many subsidiary matches 0: aaaa 1: aaa 2: aa \O8aaaa 0: aaaa 1: aaa 2: aa 3: a /ab\Cde/ abXde 0: abXde /(?<=ab\Cde)X/ abZdeX 0: X /^\R/ \r\P 0: \x0d \r\P\P Partial match: \x0d /^\R{2,3}x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P Partial match: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P Partial match: \x0d\x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d \r\rx 0: \x0d\x0dx \r\r\rx 0: \x0d\x0d\x0dx /^\R{2,3}?x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P Partial match: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P Partial match: \x0d\x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d \r\rx 0: \x0d\x0dx \r\r\rx 0: \x0d\x0d\x0dx /^\R?x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d x 0: x \rx 0: \x0dx /^\R+x/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\n\P Partial match: \x0d\x0a \r\n\P\P Partial match: \x0d\x0a \rx 0: \x0dx /^a$/ a\r\P Partial match: a\x0d a\r\P\P Partial match: a\x0d /^a$/m a\r\P Partial match: a\x0d a\r\P\P Partial match: a\x0d /^(a$|a\r)/ a\r\P 0: a\x0d a\r\P\P Partial match: a\x0d /^(a$|a\r)/m a\r\P 0: a\x0d a\r\P\P Partial match: a\x0d /./ \r\P 0: \x0d \r\P\P Partial match: \x0d /.{2,3}/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P 0: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P 0: \x0d\x0d\x0d 1: \x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d /.{2,3}?/ \r\P Partial match: \x0d \r\P\P Partial match: \x0d \r\r\P 0: \x0d\x0d \r\r\P\P Partial match: \x0d\x0d \r\r\r\P 0: \x0d\x0d\x0d 1: \x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d /-- Test simple validity check for restarts --/ /abcdef/ abc\R Error -30 (invalid data in workspace for DFA restart) /)(.)|(?R))++)*F>/ text text xxxxx text F> text2 more text. 0: text xxxxx text F> /^(?>.{4})abc|^\w\w.xabcd/ xxxxabcd 0: xxxxabcd 1: xxxxabc xx\xa0xabcd 0: xx\xa0xabcd 1: xx\xa0xabc /^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ xxxxxxxxabcd 0: xxxxxxxxabcd 1: xxxxxxxxabc xx\xa0xxxxxabcd 0: xx\xa0xxxxxabcd 1: xx\xa0xxxxxabc /-- End of testinput8 --/ pcre-8.31/testdata/testoutput90000644000222100022210000015743211762205277013415 00000000000000/-- This set of tests checks UTF-8 support with the DFA matching functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running it. --/ /\x{100}ab/8 \x{100}ab 0: \x{100}ab /a\x{100}*b/8 ab 0: ab a\x{100}b 0: a\x{100}b a\x{100}\x{100}b 0: a\x{100}\x{100}b /a\x{100}+b/8 a\x{100}b 0: a\x{100}b a\x{100}\x{100}b 0: a\x{100}\x{100}b *** Failers No match ab No match /\bX/8 Xoanon 0: X +Xoanon 0: X \x{300}Xoanon 0: X *** Failers No match YXoanon No match /\BX/8 YXoanon 0: X *** Failers No match Xoanon No match +Xoanon No match \x{300}Xoanon No match /X\b/8 X+oanon 0: X ZX\x{300}oanon 0: X FAX 0: X *** Failers No match Xoanon No match /X\B/8 Xoanon 0: X *** Failers No match X+oanon No match ZX\x{300}oanon No match FAX No match /[^a]/8 abcd 0: b a\x{100} 0: \x{100} /^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 ab99 0: ab9 \x{123}\x{123}45 0: \x{123}\x{123}4 \x{400}\x{401}\x{402}6 0: \x{400}\x{401}\x{402}6 *** Failers No match d99 No match \x{123}\x{122}4 No match \x{400}\x{403}6 No match \x{400}\x{401}\x{402}\x{402}6 No match /a.b/8 acb 0: acb a\x7fb 0: a\x{7f}b a\x{100}b 0: a\x{100}b *** Failers No match a\nb No match /a(.{3})b/8 a\x{4000}xyb 0: a\x{4000}xyb a\x{4000}\x7fyb 0: a\x{4000}\x{7f}yb a\x{4000}\x{100}yb 0: a\x{4000}\x{100}yb *** Failers No match a\x{4000}b No match ac\ncb No match /a(.*?)(.)/ a\xc0\x88b 0: a\xc0\x88b 1: a\xc0\x88 2: a\xc0 /a(.*?)(.)/8 a\x{100}b 0: a\x{100}b 1: a\x{100} /a(.*)(.)/ a\xc0\x88b 0: a\xc0\x88b 1: a\xc0\x88 2: a\xc0 /a(.*)(.)/8 a\x{100}b 0: a\x{100}b 1: a\x{100} /a(.)(.)/ a\xc0\x92bcd 0: a\xc0\x92 /a(.)(.)/8 a\x{240}bcd 0: a\x{240}b /a(.?)(.)/ a\xc0\x92bcd 0: a\xc0\x92 1: a\xc0 /a(.?)(.)/8 a\x{240}bcd 0: a\x{240}b 1: a\x{240} /a(.??)(.)/ a\xc0\x92bcd 0: a\xc0\x92 1: a\xc0 /a(.??)(.)/8 a\x{240}bcd 0: a\x{240}b 1: a\x{240} /a(.{3})b/8 a\x{1234}xyb 0: a\x{1234}xyb a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b *** Failers No match a\x{1234}b No match ac\ncb No match /a(.{3,})b/8 a\x{1234}xyb 0: a\x{1234}xyb a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb 0: axxxxbcdefghijb 1: axxxxb a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b *** Failers No match a\x{1234}b No match /a(.{3,}?)b/8 a\x{1234}xyb 0: a\x{1234}xyb a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb 0: axxxxbcdefghijb 1: axxxxb a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b *** Failers No match a\x{1234}b No match /a(.{3,5})b/8 a\x{1234}xyb 0: a\x{1234}xyb a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb 0: axxxxb a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b axbxxbcdefghijb 0: axbxxb axxxxxbcdefghijb 0: axxxxxb *** Failers No match a\x{1234}b No match axxxxxxbcdefghijb No match /a(.{3,5}?)b/8 a\x{1234}xyb 0: a\x{1234}xyb a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b axxxxbcdefghijb 0: axxxxb a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b axbxxbcdefghijb 0: axbxxb axxxxxbcdefghijb 0: axxxxxb *** Failers No match a\x{1234}b No match axxxxxxbcdefghijb No match /^[a\x{c0}]/8 *** Failers No match \x{100} No match /(?<=aXb)cd/8 aXbcd 0: cd /(?<=a\x{100}b)cd/8 a\x{100}bcd 0: cd /(?<=a\x{100000}b)cd/8 a\x{100000}bcd 0: cd /(?:\x{100}){3}b/8 \x{100}\x{100}\x{100}b 0: \x{100}\x{100}\x{100}b *** Failers No match \x{100}\x{100}b No match /\x{ab}/8 \x{ab} 0: \x{ab} \xc2\xab 0: \x{ab} *** Failers No match \x00{ab} No match /(?<=(.))X/8 WXYZ 0: X \x{256}XYZ 0: X *** Failers No match XYZ No match /[^a]+/8g bcd 0: bcd 1: bc 2: b \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z 1: Y\x{256} 2: Y /^[^a]{2}/8 \x{100}bc 0: \x{100}b /^[^a]{2,}/8 \x{100}bcAa 0: \x{100}bcA 1: \x{100}bc 2: \x{100}b /^[^a]{2,}?/8 \x{100}bca 0: \x{100}bc 1: \x{100}b /[^a]+/8ig bcd 0: bcd 1: bc 2: b \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z 1: Y\x{256} 2: Y /^[^a]{2}/8i \x{100}bc 0: \x{100}b /^[^a]{2,}/8i \x{100}bcAa 0: \x{100}bc 1: \x{100}b /^[^a]{2,}?/8i \x{100}bca 0: \x{100}bc 1: \x{100}b /\x{100}{0,0}/8 abcd 0: /\x{100}?/8 abcd 0: \x{100}\x{100} 0: \x{100} 1: /\x{100}{0,3}/8 \x{100}\x{100} 0: \x{100}\x{100} 1: \x{100} 2: \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} 1: \x{100}\x{100} 2: \x{100} 3: /\x{100}*/8 abce 0: \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} 1: \x{100}\x{100}\x{100} 2: \x{100}\x{100} 3: \x{100} 4: /\x{100}{1,1}/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100} /\x{100}{1,3}/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} 1: \x{100}\x{100} 2: \x{100} /\x{100}+/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} 1: \x{100}\x{100}\x{100} 2: \x{100}\x{100} 3: \x{100} /\x{100}{3}/8 abcd\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100} /\x{100}{3,5}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100} 1: \x{100}\x{100}\x{100}\x{100} 2: \x{100}\x{100}\x{100} /\x{100}{3,}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 2: \x{100}\x{100}\x{100}\x{100}\x{100} 3: \x{100}\x{100}\x{100}\x{100} 4: \x{100}\x{100}\x{100} /(?<=a\x{100}{2}b)X/8 Xyyya\x{100}\x{100}bXzzz 0: X /\D*/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Matched, but too many subsidiary matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 3: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 4: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 6: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 7: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 8: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 10: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 11: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 12: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 13: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 14: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 15: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 16: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 17: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 18: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 19: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /\D*/8 \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} Matched, but too many subsidiary matches 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 2: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 3: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 4: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 5: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 6: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 7: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 8: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 9: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 10: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 11: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 12: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 13: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 14: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 15: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 16: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 17: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 18: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 19: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 20: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 21: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /\D/8 1X2 0: X 1\x{100}2 0: \x{100} />\S/8 > >X Y 0: >X > >\x{100} Y 0: >\x{100} /\d/8 \x{100}3 0: 3 /\s/8 \x{100} X 0: /\D+/8 12abcd34 0: abcd 1: abc 2: ab 3: a *** Failers 0: *** Failers 1: *** Failer 2: *** Faile 3: *** Fail 4: *** Fai 5: *** Fa 6: *** F 7: *** 8: *** 9: ** 10: * 1234 No match /\D{2,3}/8 12abcd34 0: abc 1: ab 12ab34 0: ab *** Failers 0: *** 1: ** 1234 No match 12a34 No match /\D{2,3}?/8 12abcd34 0: abc 1: ab 12ab34 0: ab *** Failers 0: *** 1: ** 1234 No match 12a34 No match /\d+/8 12abcd34 0: 12 1: 1 *** Failers No match /\d{2,3}/8 12abcd34 0: 12 1234abcd 0: 123 1: 12 *** Failers No match 1.4 No match /\d{2,3}?/8 12abcd34 0: 12 1234abcd 0: 123 1: 12 *** Failers No match 1.4 No match /\S+/8 12abcd34 0: 12abcd34 1: 12abcd3 2: 12abcd 3: 12abc 4: 12ab 5: 12a 6: 12 7: 1 *** Failers 0: *** 1: ** 2: * \ \ No match /\S{2,3}/8 12abcd34 0: 12a 1: 12 1234abcd 0: 123 1: 12 *** Failers 0: *** 1: ** \ \ No match /\S{2,3}?/8 12abcd34 0: 12a 1: 12 1234abcd 0: 123 1: 12 *** Failers 0: *** 1: ** \ \ No match />\s+ <34 0: > < *** Failers No match />\s{2,3} < ab> < *** Failers No match ab> \s{2,3}? < ab> < *** Failers No match ab> \xff< 0: \xff /[\xff]/8 >\x{ff}< 0: \x{ff} /[^\xFF]/ XYZ 0: X /[^\xff]/8 XYZ 0: X \x{123} 0: \x{123} /^[ac]*b/8 xb No match /^[ac\x{100}]*b/8 xb No match /^[^x]*b/8i xb No match /^[^x]*b/8 xb No match /^\d*b/8 xb No match /(|a)/g8 catac 0: 0: a 1: 0: 0: a 1: 0: 0: a\x{256}a 0: a 1: 0: 0: a 1: 0: /^\x{85}$/8i \x{85} 0: \x{85} /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc7 0: abc8 0: abc9 /abc.$/mgx8 abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 0: abc7 0: abc8 0: abc9 /^a\Rb/8 a\nb 0: a\x{0a}b a\rb 0: a\x{0d}b a\r\nb 0: a\x{0d}\x{0a}b a\x0bb 0: a\x{0b}b a\x0cb 0: a\x{0c}b a\x{85}b 0: a\x{85}b a\x{2028}b 0: a\x{2028}b a\x{2029}b 0: a\x{2029}b ** Failers No match a\n\rb No match /^a\R*b/8 ab 0: ab a\nb 0: a\x{0a}b a\rb 0: a\x{0d}b a\r\nb 0: a\x{0d}\x{0a}b a\x0bb 0: a\x{0b}b a\x0c\x{2028}\x{2029}b 0: a\x{0c}\x{2028}\x{2029}b a\x{85}b 0: a\x{85}b a\n\rb 0: a\x{0a}\x{0d}b a\n\r\x{85}\x0cb 0: a\x{0a}\x{0d}\x{85}\x{0c}b /^a\R+b/8 a\nb 0: a\x{0a}b a\rb 0: a\x{0d}b a\r\nb 0: a\x{0d}\x{0a}b a\x0bb 0: a\x{0b}b a\x0c\x{2028}\x{2029}b 0: a\x{0c}\x{2028}\x{2029}b a\x{85}b 0: a\x{85}b a\n\rb 0: a\x{0a}\x{0d}b a\n\r\x{85}\x0cb 0: a\x{0a}\x{0d}\x{85}\x{0c}b ** Failers No match ab No match /^a\R{1,3}b/8 a\nb 0: a\x{0a}b a\n\rb 0: a\x{0a}\x{0d}b a\n\r\x{85}b 0: a\x{0a}\x{0d}\x{85}b a\r\n\r\nb 0: a\x{0d}\x{0a}\x{0d}\x{0a}b a\r\n\r\n\r\nb 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b a\n\r\n\rb 0: a\x{0a}\x{0d}\x{0a}\x{0d}b a\n\n\r\nb 0: a\x{0a}\x{0a}\x{0d}\x{0a}b ** Failers No match a\n\n\n\rb No match a\r No match /\h+\V?\v{3,4}/8 \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} /\V?\v{3,4}/8 \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a 0: X\x{0a}\x{0b}\x{0c}\x{0d} 1: X\x{0a}\x{0b}\x{0c} /\h+\V?\v{3,4}/8 >\x09\x20\x{a0}X\x0a\x0a\x0a< 0: \x{09} \x{a0}X\x{0a}\x{0a}\x{0a} /\V?\v{3,4}/8 >\x09\x20\x{a0}X\x0a\x0a\x0a< 0: X\x{0a}\x{0a}\x{0a} /\H\h\V\v/8 X X\x0a 0: X X\x{0a} X\x09X\x0b 0: X\x{09}X\x{0b} ** Failers No match \x{a0} X\x0a No match /\H*\h+\V?\v{3,4}/8 \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} 1: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} \x09\x20\x{a0}\x0a\x0b\x0c 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} ** Failers No match \x09\x20\x{a0}\x0a\x0b No match /\H\h\V\v/8 \x{3001}\x{3000}\x{2030}\x{2028} 0: \x{3001}\x{3000}\x{2030}\x{2028} X\x{180e}X\x{85} 0: X\x{180e}X\x{85} ** Failers No match \x{2009} X\x0a No match /\H*\h+\V?\v{3,4}/8 \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d} 1: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c} \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028} 1: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c} \x09\x20\x{202f}\x0a\x0b\x0c 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} ** Failers No match \x09\x{200a}\x{a0}\x{2028}\x0b No match /a\Rb/I8 Capturing subpattern count = 0 Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b ** Failers No match a\x{85}b No match a\x0bb No match /a\Rb/I8 Capturing subpattern count = 0 Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b a\x{85}b 0: a\x{85}b a\x0bb 0: a\x{0b}b ** Failers No match a\x{85}b\ No match a\x0bb\ No match /a\R?b/I8 Capturing subpattern count = 0 Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b ** Failers No match a\x{85}b No match a\x0bb No match /a\R?b/I8 Capturing subpattern count = 0 Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb 0: a\x{0d}b a\nb 0: a\x{0a}b a\r\nb 0: a\x{0d}\x{0a}b a\x{85}b 0: a\x{85}b a\x0bb 0: a\x{0b}b ** Failers No match a\x{85}b\ No match a\x0bb\ No match /X/8f A\x{1ec5}ABCXYZ 0: X /abcd*/8 xxxxabcd\P 0: abcd 1: abc xxxxabcd\P\P Partial match: abcd /abcd*/i8 xxxxabcd\P 0: abcd 1: abc xxxxabcd\P\P Partial match: abcd XXXXABCD\P 0: ABCD 1: ABC XXXXABCD\P\P Partial match: ABCD /abc\d*/8 xxxxabc1\P 0: abc1 1: abc xxxxabc1\P\P Partial match: abc1 /abc[de]*/8 xxxxabcde\P 0: abcde 1: abcd 2: abc xxxxabcde\P\P Partial match: abcde /\bthe cat\b/8 the cat\P 0: the cat the cat\P\P Partial match: the cat /ab\Cde/8 abXde Error -16 (item unsupported for DFA matching) /(?<=ab\Cde)X/8 Failed: \C not allowed in lookbehind assertion at offset 10 /./8 \r\P 0: \x{0d} \r\P\P Partial match: \x{0d} /.{2,3}/8 \r\P Partial match: \x{0d} \r\P\P Partial match: \x{0d} \r\r\P 0: \x{0d}\x{0d} \r\r\P\P Partial match: \x{0d}\x{0d} \r\r\r\P 0: \x{0d}\x{0d}\x{0d} 1: \x{0d}\x{0d} \r\r\r\P\P Partial match: \x{0d}\x{0d}\x{0d} /.{2,3}?/8 \r\P Partial match: \x{0d} \r\P\P Partial match: \x{0d} \r\r\P 0: \x{0d}\x{0d} \r\r\P\P Partial match: \x{0d}\x{0d} \r\r\r\P 0: \x{0d}\x{0d}\x{0d} 1: \x{0d}\x{0d} \r\r\r\P\P Partial match: \x{0d}\x{0d}\x{0d} /[^\x{100}]/8 \x{100}\x{101}X 0: \x{101} /[^\x{100}]+/8 \x{100}\x{101}X 0: \x{101}X 1: \x{101} /-- End of testinput9 --/ pcre-8.31/testdata/testinput100000644000222100022210000003574011762205217013253 00000000000000/-- This set of tests check Unicode property support with the DFA matching functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running it. --/ /\pL\P{Nd}/8 AB *** Failers A0 00 /\X./8 AB A\x{300}BC A\x{300}\x{301}\x{302}BC *** Failers \x{300} /\X\X/8 ABC A\x{300}B\x{300}\x{301}C A\x{300}\x{301}\x{302}BC *** Failers \x{300} /^\pL+/8 abcd a *** Failers /^\PL+/8 1234 = *** Failers abcd /^\X+/8 abcdA\x{300}\x{301}\x{302} A\x{300}\x{301}\x{302} A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} a *** Failers \x{300}\x{301}\x{302} /\X?abc/8 abc A\x{300}abc A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz \x{300}abc *** Failers /^\X?abc/8 abc A\x{300}abc *** Failers A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz \x{300}abc /\X*abc/8 abc A\x{300}abc A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz \x{300}abc *** Failers /^\X*abc/8 abc A\x{300}abc A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz *** Failers \x{300}abc /^\pL?=./8 A=b =c *** Failers 1=2 AAAA=b /^\pL*=./8 AAAA=b =c *** Failers 1=2 /^\X{2,3}X/8 A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X *** Failers X A\x{300}\x{301}\x{302}X A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X /^\pC\pL\pM\pN\pP\pS\pZ\p{Xsp}/8 >\x{1680}\x{2028}\x{0b} ** Failers \x{0b} /^>\p{Xsp}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>[\p{Xsp}]/8 >\x{2028}\x{0b} /^>[\p{Xsp}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}/8 >\x{1680}\x{2028}\x{0b} >\x{a0} ** Failers \x{0b} /^>\p{Xps}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}+?/8 >\x{1680}\x{2028}\x{0b} /^>\p{Xps}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>[\p{Xps}]/8 >\x{2028}\x{0b} /^>[\p{Xps}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^\p{Xwd}/8 ABCD 1234 \x{6ca} \x{a6c} \x{10a7} _ABC ** Failers [] /^\p{Xwd}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xwd}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /^\p{Xwd}{2,9}/8 A_12\x{6ca}\x{a6c}\x{10a7} /^[\p{Xwd}]/8 ABCD1234_ 1234abcd_ \x{6ca} \x{a6c} \x{10a7} _ABC ** Failers [] /^[\p{Xwd}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ /-- Unicode properties for \b abd \B --/ /\b...\B/8W abc_ \x{37e}abc\x{376} \x{37e}\x{376}\x{371}\x{393}\x{394} !\x{c0}++\x{c1}\x{c2} !\x{c0}+++++ /-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ /\b...\B/8 abc_ ** Failers \x{37e}abc\x{376} \x{37e}\x{376}\x{371}\x{393}\x{394} !\x{c0}++\x{c1}\x{c2} !\x{c0}+++++ /-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ /\b...\B/W abc_ !\x{c0}++\x{c1}\x{c2} !\x{c0}+++++ /-- Caseless single negated characters > 127 need UCP support --/ /[^\x{100}]/8i \x{100}\x{101}X /[^\x{100}]+/8i \x{100}\x{101}XX /^\X/8 A\P A\P\P A\x{300}\x{301}\P A\x{300}\x{301}\P\P A\x{301}\P A\x{301}\P\P /^\X{2,3}/8 A\P A\P\P AA\P AA\P\P A\x{300}\x{301}\P A\x{300}\x{301}\P\P A\x{300}\x{301}A\x{300}\x{301}\P A\x{300}\x{301}A\x{300}\x{301}\P\P /^\X{2}/8 AA\P AA\P\P A\x{300}\x{301}A\x{300}\x{301}\P A\x{300}\x{301}A\x{300}\x{301}\P\P /^\X+/8 AA\P AA\P\P /^\X+?Z/8 AA\P AA\P\P /-- End of testinput10 --/ pcre-8.31/testdata/testinput110000644000222100022210000000516611676645223013264 00000000000000/-- These are a few representative patterns whose lengths and offsets are to be shown when the link size is 2. This is just a doublecheck test to ensure the sizes don't go horribly wrong when something is changed. The pattern contents are all themselves checked in other tests. Unicode, including property support, is required for these tests. --/ /((?i)b)/BM /(?s)(.*X|^B)/BM /(?s:.*X|^B)/BM /^[[:alnum:]]/BM /#/IxMD /a#/IxMD /x?+/BM /x++/BM /x{1,3}+/BM /(x)*+/BM /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM |8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM /(a(?1)b)/BM /(a(?1)+b)/BM /a(?Pb|c)d(?Pe)/BM /(?:a(?Pc(?Pd)))(?Pa)/BM /(?Pa)...(?P=a)bbb(?P>a)d/BM /abc(?C255)de(?C)f/BM /abcde/CBM /\x{100}/8BM /\x{1000}/8BM /\x{10000}/8BM /\x{100000}/8BM /\x{10ffff}/8BM /\x{110000}/8BM /[\x{ff}]/8BM /[\x{100}]/8BM /\x80/8BM /\xff/8BM /\x{0041}\x{2262}\x{0391}\x{002e}/D8M /\x{D55c}\x{ad6d}\x{C5B4}/D8M /\x{65e5}\x{672c}\x{8a9e}/D8M /[\x{100}]/8BM /[Z\x{100}]/8BM /^[\x{100}\E-\Q\E\x{150}]/B8M /^[\QÄ€\E-\QÅ\E]/B8M /^[\QÄ€\E-\QÅ\E/B8M /[\p{L}]/BM /[\p{^L}]/BM /[\P{L}]/BM /[\P{^L}]/BM /[abc\p{L}\x{0660}]/8BM /[\p{Nd}]/8BM /[\p{Nd}+-]+/8BM /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM /[\x{105}-\x{109}]/8iBM /( ( (?(1)0|) )* )/xBM /( (?(1)0|)* )/xBM /[a]/BM /[a]/8BM /[\xaa]/BM /[\xaa]/8BM /[^a]/BM /[^a]/8BM /[^\xaa]/BM /[^\xaa]/8BM /[^\d]/8WB /[[:^alpha:][:^cntrl:]]+/8WB /[[:^cntrl:][:^alpha:]]+/8WB /[[:alpha:]]+/8WB /[[:^alpha:]\S]+/8WB /abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B /-- End of testinput11 --/ pcre-8.31/testdata/testinput120000644000222100022210000000162211741324730013244 00000000000000/-- This test is run only when JIT support is available. It checks for a successful and an unsuccessful JIT compile and save and restore behaviour, and a couple of things that are different with JIT. --/ /abc/S+I /ab(*THEN)/S+I /abc/S+I>testsavedregex b)c/PN abc /a?|b?/P abc ** Failers ddd\N /\w+A/P CDAAAAB /\w+A/PU CDAAAAB /\Biss\B/I+P Mississippi /abc/\P /-- End of POSIX tests --/ /a\Cb/ aXb a\nb ** Failers (too big char) A\x{123}B /\x{100}/I / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /xSI /-- Although this saved pattern was compiled with link-size=2, it does no harm to run this test with other link sizes because it is going to generated a "compiled in wrong mode" error as soon as it is loaded, so the link size does not matter. --/ \x09< /[\h]+/BZ >\x09\x20\xa0< /[\v]/BZ /[\H]/BZ /[^\h]/BZ /[\V]/BZ /[\x0a\V]/BZ /\777/I /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K XX /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K XX /\u0100/ /[\u0100-\u0200]/ /-- End of testinput14 --/ pcre-8.31/testdata/testinput150000644000222100022210000001017011767405216013254 00000000000000/-- This set of tests is for UTF-8 support, and is relevant only to the 8-bit library. --/ /X(\C{3})/8 X\x{1234} /X(\C{4})/8 X\x{1234}YZ /X\C*/8 XYZabcdce /X\C*?/8 XYZabcde /X\C{3,5}/8 Xabcdefg X\x{1234} X\x{1234}YZ X\x{1234}\x{512} X\x{1234}\x{512}YZ /X\C{3,5}?/8 Xabcdefg X\x{1234} X\x{1234}YZ X\x{1234}\x{512} /a\Cb/8 aXb a\nb /a\C\Cb/8 a\x{100}b /ab\Cde/8 abXde /a\C\Cb/8 a\x{100}b ** Failers a\x{12257}b /[Ã]/8 /Ã/8 /ÃÃÃxxx/8 /ÃÃÃxxx/8?DZSS /abc/8 Ã] à ÃÃà ÃÃÃ\? \xe1\x88 \P\xe1\x88 \P\P\xe1\x88 XX\xea \O0XX\xea \O1XX\xea \O2XX\xea XX\xf1 XX\xf8 XX\xfc ZZ\xea\xaf\x20YY ZZ\xfd\xbf\xbf\x2f\xbf\xbfYY ZZ\xfd\xbf\xbf\xbf\x2f\xbfYY ZZ\xfd\xbf\xbf\xbf\xbf\x2fYY ZZ\xffYY ZZ\xfeYY /anything/8 \xc0\x80 \xc1\x8f \xe0\x9f\x80 \xf0\x8f\x80\x80 \xf8\x87\x80\x80\x80 \xfc\x83\x80\x80\x80\x80 \xfe\x80\x80\x80\x80\x80 \xff\x80\x80\x80\x80\x80 \xc3\x8f \xe0\xaf\x80 \xe1\x80\x80 \xf0\x9f\x80\x80 \xf1\x8f\x80\x80 \xf8\x88\x80\x80\x80 \xf9\x87\x80\x80\x80 \xfc\x84\x80\x80\x80\x80 \xfd\x83\x80\x80\x80\x80 \?\xf8\x88\x80\x80\x80 \?\xf9\x87\x80\x80\x80 \?\xfc\x84\x80\x80\x80\x80 \?\xfd\x83\x80\x80\x80\x80 /\x{100}/8DZ /\x{1000}/8DZ /\x{10000}/8DZ /\x{100000}/8DZ /\x{10ffff}/8DZ /[\x{ff}]/8DZ /[\x{100}]/8DZ /\x80/8DZ /\xff/8DZ /\x{D55c}\x{ad6d}\x{C5B4}/DZ8 \x{D55c}\x{ad6d}\x{C5B4} /\x{65e5}\x{672c}\x{8a9e}/DZ8 \x{65e5}\x{672c}\x{8a9e} /\x{80}/DZ8 /\x{084}/DZ8 /\x{104}/DZ8 /\x{861}/DZ8 /\x{212ab}/DZ8 /-- This one is here not because it's different to Perl, but because the way the captured single-byte is displayed. (In Perl it becomes a character, and you can't tell the difference.) --/ /X(\C)(.*)/8 X\x{1234} X\nabc /-- This one is here because Perl gives out a grumbly error message (quite correctly, but that messes up comparisons). --/ /a\Cb/8 *** Failers a\x{100}b /[^ab\xC0-\xF0]/8SDZ \x{f1} \x{bf} \x{100} \x{1000} *** Failers \x{c0} \x{f0} /Ä€{3,4}/8SDZ \x{100}\x{100}\x{100}\x{100\x{100} /(\x{100}+|x)/8SDZ /(\x{100}*a|x)/8SDZ /(\x{100}{0,2}a|x)/8SDZ /(\x{100}{1,2}a|x)/8SDZ /\x{100}/8DZ /a\x{100}\x{101}*/8DZ /a\x{100}\x{101}+/8DZ /[^\x{c4}]/DZ /[\x{100}]/8DZ \x{100} Z\x{100} \x{100}Z *** Failers /[\xff]/DZ8 >\x{ff}< /[^\xff]/8DZ /\x{100}abc(xyz(?1))/8DZ /a\x{1234}b/P8 a\x{1234}b /\777/8I \x{1ff} \777 /\x{100}+\x{200}/8DZ /\x{100}+X/8DZ /^[\QÄ€\E-\QÅ\E/BZ8 /-- This tests the stricter UTF-8 check according to RFC 3629. --/ /X/8 \x{0}\x{d7ff}\x{e000}\x{10ffff} \x{d800} \x{d800}\? \x{da00} \x{da00}\? \x{dfff} \x{dfff}\? \x{110000} \x{110000}\? \x{2000000} \x{2000000}\? \x{7fffffff} \x{7fffffff}\? /(*UTF8)\x{1234}/ abcd\x{1234}pqr /(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I /\h/SI8 ABC\x{09} ABC\x{20} ABC\x{a0} ABC\x{1680} ABC\x{180e} ABC\x{2000} ABC\x{202f} ABC\x{205f} ABC\x{3000} /\v/SI8 ABC\x{0a} ABC\x{0b} ABC\x{0c} ABC\x{0d} ABC\x{85} ABC\x{2028} /\h*A/SI8 CDBABC /\v+A/SI8 /\s?xxx\s/8SI /\sxxx\s/I8ST1 AB\x{85}xxx\x{a0}XYZ AB\x{a0}xxx\x{85}XYZ /\S \S/I8ST1 \x{a2} \x{84} A Z /a+/8 a\x{123}aa\>1 a\x{123}aa\>2 a\x{123}aa\>3 a\x{123}aa\>4 a\x{123}aa\>5 a\x{123}aa\>6 /\x{1234}+/iS8I /\x{1234}+?/iS8I /\x{1234}++/iS8I /\x{1234}{2}/iS8I /[^\x{c4}]/8DZ /X+\x{200}/8DZ /\R/SI8 /\777/8DZ /\w+\x{C4}/8BZ a\x{C4}\x{C4} /\w+\x{C4}/8BZT1 a\x{C4}\x{C4} /\W+\x{C4}/8BZ !\x{C4} /\W+\x{C4}/8BZT1 !\x{C4} /\W+\x{A1}/8BZ !\x{A1} /\W+\x{A1}/8BZT1 !\x{A1} /X\s+\x{A0}/8BZ X\x20\x{A0}\x{A0} /X\s+\x{A0}/8BZT1 X\x20\x{A0}\x{A0} /\S+\x{A0}/8BZ X\x{A0}\x{A0} /\S+\x{A0}/8BZT1 X\x{A0}\x{A0} /\x{a0}+\s!/8BZ \x{a0}\x20! /\x{a0}+\s!/8BZT1 \x{a0}\x20! /-- End of testinput15 --/ pcre-8.31/testdata/testinput160000644000222100022210000000152111676645223013260 00000000000000/-- This set of tests is run only with the 8-bit library when Unicode property support is available. It starts with tests of the POSIX interface, because that is supported only with the 8-bit library. --/ /\w/P +++\x{c2} /\w/WP +++\x{c2} /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ /AB\x{1fb0}/8DZ /AB\x{1fb0}/8DZi /\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} /[â±¥]/8iBZ /[^â±¥]/8iBZ /\h/SI /\v/SI /\R/SI /[[:blank:]]/WBZ /-- End of testinput16 --/ pcre-8.31/testdata/testinput170000644000222100022210000003076211767405305013266 00000000000000/-- This set of tests is for the 16-bit library's basic (non-UTF-16) features that are not compatible with the 8-bit library, or which give different output in 16-bit mode. --/ /a\Cb/ aXb a\nb /-- Check maximum non-UTF character size --/ /\x{ffff}/ A\x{ffff}B /\x{10000}/ /[^\x{c4}]/DZ /\x{100}/I / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /xSI /[\h]/BZ >\x09< /[\h]+/BZ >\x09\x20\xa0< /[\v]/BZ /[\H]/BZ /[^\h]/BZ /[\V]/BZ /[\x0a\V]/BZ /\h+/SI \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\xa0\x{2000} /[\h\x{dc00}]+/BZSI \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} \x{3001}\x{2fff}\x{200a}\xa0\x{2000} /\H+/SI \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} /[\H\x{d800}]+/BZSI \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} \x{2000}\x{200a}\x{1fff}\x{200b} \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} /\v+/SI \x{2027}\x{2030}\x{2028}\x{2029} \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d /[\v\x{dc00}]+/BZSI \x{2027}\x{2030}\x{2028}\x{2029} \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d /\V+/SI \x{2028}\x{2029}\x{2027}\x{2030} \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 /[\V\x{d800}]+/BZSI \x{2028}\x{2029}\x{2027}\x{2030} \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 /\R+/SI \x{2027}\x{2030}\x{2028}\x{2029} \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d /\x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}/I \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} /[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZ /[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZi /[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZ /[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZi /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K XX /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K XX /\u0100/BZ /[\u0100-\u0200]/BZ /\ud800/BZ /-- End of testinput17 --/ pcre-8.31/testdata/testinput180000644000222100022210000000662711775523523013274 00000000000000/-- This set of tests is for UTF-16 support, and is relevant only to the 16-bit library. --/ /ÃÃÃxxx/8?DZSS /abc/8 Ã] /X(\C{3})/8 X\x{11234}Y /X(\C{4})/8 X\x{11234}YZ /X\C*/8 XYZabcdce /X\C*?/8 XYZabcde /X\C{3,5}/8 Xabcdefg X\x{11234}Y X\x{11234}YZ X\x{11234}\x{512} X\x{11234}\x{512}YZ X\x{11234}\x{512}\x{11234}Z /X\C{3,5}?/8 Xabcdefg X\x{11234}Y X\x{11234}YZ X\x{11234}\x{512}YZ *** Failers X\x{11234} /a\Cb/8 aXb a\nb /a\C\Cb/8 a\x{12257}b ** Failers a\x{100}b /ab\Cde/8 abXde /-- Check maximum character size --/ /\x{ffff}/8DZ /\x{10000}/8DZ /\x{100}/8DZ /\x{1000}/8DZ /\x{10000}/8DZ /\x{100000}/8DZ /\x{10ffff}/8DZ /[\x{ff}]/8DZ /[\x{100}]/8DZ /\x80/8DZ /\xff/8DZ /\x{D55c}\x{ad6d}\x{C5B4}/DZ8 \x{D55c}\x{ad6d}\x{C5B4} /\x{65e5}\x{672c}\x{8a9e}/DZ8 \x{65e5}\x{672c}\x{8a9e} /\x{80}/DZ8 /\x{084}/DZ8 /\x{104}/DZ8 /\x{861}/DZ8 /\x{212ab}/DZ8 /-- This one is here not because it's different to Perl, but because the way the captured single-byte is displayed. (In Perl it becomes a character, and you can't tell the difference.) --/ /X(\C)(.*)/8 X\x{1234} X\nabc /-- This one is here because Perl gives out a grumbly error message (quite correctly, but that messes up comparisons). --/ /a\Cb/8 *** Failers a\x{100}b /[^ab\xC0-\xF0]/8SDZ \x{f1} \x{bf} \x{100} \x{1000} *** Failers \x{c0} \x{f0} /Ä€{3,4}/8SDZ \x{100}\x{100}\x{100}\x{100\x{100} /(\x{100}+|x)/8SDZ /(\x{100}*a|x)/8SDZ /(\x{100}{0,2}a|x)/8SDZ /(\x{100}{1,2}a|x)/8SDZ /\x{100}/8DZ /a\x{100}\x{101}*/8DZ /a\x{100}\x{101}+/8DZ /[^\x{c4}]/DZ /[\x{100}]/8DZ \x{100} Z\x{100} \x{100}Z *** Failers /[\xff]/DZ8 >\x{ff}< /[^\xff]/8DZ /\x{100}abc(xyz(?1))/8DZ /\777/8I \x{1ff} \777 /\x{100}+\x{200}/8DZ /\x{100}+X/8DZ /^[\QÄ€\E-\QÅ\E/BZ8 /X/8 \x{0}\x{d7ff}\x{e000}\x{10ffff} \x{d800} \x{d800}\? \x{da00} \x{da00}\? \x{dc00} \x{dc00}\? \x{de00} \x{de00}\? \x{dfff} \x{dfff}\? \x{110000} \x{d800}\x{1234} \x{fffe} /(*UTF16)\x{11234}/ abcd\x{11234}pqr /(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I /\h/SI8 ABC\x{09} ABC\x{20} ABC\x{a0} ABC\x{1680} ABC\x{180e} ABC\x{2000} ABC\x{202f} ABC\x{205f} ABC\x{3000} /\v/SI8 ABC\x{0a} ABC\x{0b} ABC\x{0c} ABC\x{0d} ABC\x{85} ABC\x{2028} /\h*A/SI8 CDBABC \x{2000}ABC /\R*A/SI8 CDBABC \x{2028}A /\v+A/SI8 /\s?xxx\s/8SI /\sxxx\s/I8ST1 AB\x{85}xxx\x{a0}XYZ AB\x{a0}xxx\x{85}XYZ /\S \S/I8ST1 \x{a2} \x{84} A Z /a+/8 a\x{123}aa\>1 a\x{123}aa\>2 a\x{123}aa\>3 a\x{123}aa\>4 a\x{123}aa\>5 a\x{123}aa\>6 /\x{1234}+/iS8I /\x{1234}+?/iS8I /\x{1234}++/iS8I /\x{1234}{2}/iS8I /[^\x{c4}]/8DZ /X+\x{200}/8DZ /\R/SI8 /-- Check bad offset --/ /a/8 \x{10000}\>1 \x{10000}ab\>2 \x{10000}ab\>3 \x{10000}ab\>4 \x{10000}ab\>5 /í¼€/8 /\w+\x{C4}/8BZ a\x{C4}\x{C4} /\w+\x{C4}/8BZT1 a\x{C4}\x{C4} /\W+\x{C4}/8BZ !\x{C4} /\W+\x{C4}/8BZT1 !\x{C4} /\W+\x{A1}/8BZ !\x{A1} /\W+\x{A1}/8BZT1 !\x{A1} /X\s+\x{A0}/8BZ X\x20\x{A0}\x{A0} /X\s+\x{A0}/8BZT1 X\x20\x{A0}\x{A0} /\S+\x{A0}/8BZ X\x{A0}\x{A0} /\S+\x{A0}/8BZT1 X\x{A0}\x{A0} /\x{a0}+\s!/8BZ \x{a0}\x20! /\x{a0}+\s!/8BZT1 \x{a0}\x20! /-- End of testinput18 --/ pcre-8.31/testdata/testinput190000644000222100022210000000123511676645223013265 00000000000000/-- This set of tests is for Unicode property support, relevant only to the 16-bit library. --/ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ /AB\x{1fb0}/8DZ /AB\x{1fb0}/8DZi /\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} /[â±¥]/8iBZ /[^â±¥]/8iBZ /[[:blank:]]/WBZ /-- End of testinput19 --/ pcre-8.31/testdata/testinput200000644000222100022210000000044611676645217013263 00000000000000/-- These tests are for the handling of characters greater than 255 in 16-bit, non-UTF-16 mode. --/ /^\x{ffff}+/i \x{ffff} /^\x{ffff}?/i \x{ffff} /^\x{ffff}*/i \x{ffff} /^\x{ffff}{3}/i \x{ffff}\x{ffff}\x{ffff} /^\x{ffff}{0,3}/i \x{ffff} /-- End of testinput20 --/ pcre-8.31/testdata/testinput210000644000222100022210000000056511706273000013243 00000000000000/-- Tests for reloading pre-compile patterns. The first one gives an error right away. The others require the linke size to be 2. */ (?:[AaLl]+)[^xX-]*?)(?P[\x{150}-\x{250}\x{300}]|[^\x{800}aAs-uS-U\x{d800}-\x{dfff}])++[^#\b\x{500}\x{1000}]{3,5}$ --/ [aZ\x{400}-\x{10ffff}]{4,}[\x{f123}\x{10039}\x{20000}-\x{21234}]?|[A-Cx-z\x{100000}-\x{1000a7}\x{101234}])(?[^az]) --/8 iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM Memory allocation (code space): 826 ------------------------------------------------------------------ 0 822 Bra 3 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X 821 \b 822 822 Ket 825 End ------------------------------------------------------------------ |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM Memory allocation (code space): 816 ------------------------------------------------------------------ 0 812 Bra 3 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X 811 \b 812 812 Ket 815 End ------------------------------------------------------------------ /(a(?1)b)/BM Memory allocation (code space): 22 ------------------------------------------------------------------ 0 18 Bra 3 12 CBra 1 8 a 10 3 Recurse 13 b 15 12 Ket 18 18 Ket 21 End ------------------------------------------------------------------ /(a(?1)+b)/BM Memory allocation (code space): 28 ------------------------------------------------------------------ 0 24 Bra 3 18 CBra 1 8 a 10 6 Once 13 3 Recurse 16 6 KetRmax 19 b 21 18 Ket 24 24 Ket 27 End ------------------------------------------------------------------ /a(?Pb|c)d(?Pe)/BM Memory allocation (code space): 36 ------------------------------------------------------------------ 0 32 Bra 3 a 5 7 CBra 1 10 b 12 5 Alt 15 c 17 12 Ket 20 d 22 7 CBra 2 27 e 29 7 Ket 32 32 Ket 35 End ------------------------------------------------------------------ /(?:a(?Pc(?Pd)))(?Pa)/BM Memory allocation (code space): 45 ------------------------------------------------------------------ 0 41 Bra 3 25 Bra 6 a 8 17 CBra 1 13 c 15 7 CBra 2 20 d 22 7 Ket 25 17 Ket 28 25 Ket 31 7 CBra 3 36 a 38 7 Ket 41 41 Ket 44 End ------------------------------------------------------------------ /(?Pa)...(?P=a)bbb(?P>a)d/BM Memory allocation (code space): 34 ------------------------------------------------------------------ 0 30 Bra 3 7 CBra 1 8 a 10 7 Ket 13 Any 14 Any 15 Any 16 \1 19 bbb 25 3 Recurse 28 d 30 30 Ket 33 End ------------------------------------------------------------------ /abc(?C255)de(?C)f/BM Memory allocation (code space): 31 ------------------------------------------------------------------ 0 27 Bra 3 abc 9 Callout 255 10 1 15 de 19 Callout 0 16 1 25 f 27 27 Ket 30 End ------------------------------------------------------------------ /abcde/CBM Memory allocation (code space): 53 ------------------------------------------------------------------ 0 49 Bra 3 Callout 255 0 1 9 a 11 Callout 255 1 1 17 b 19 Callout 255 2 1 25 c 27 Callout 255 3 1 33 d 35 Callout 255 4 1 41 e 43 Callout 255 5 0 49 49 Ket 52 End ------------------------------------------------------------------ /\x{100}/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 \x{100} 6 6 Ket 9 End ------------------------------------------------------------------ /\x{1000}/8BM Memory allocation (code space): 11 ------------------------------------------------------------------ 0 7 Bra 3 \x{1000} 7 7 Ket 10 End ------------------------------------------------------------------ /\x{10000}/8BM Memory allocation (code space): 12 ------------------------------------------------------------------ 0 8 Bra 3 \x{10000} 8 8 Ket 11 End ------------------------------------------------------------------ /\x{100000}/8BM Memory allocation (code space): 12 ------------------------------------------------------------------ 0 8 Bra 3 \x{100000} 8 8 Ket 11 End ------------------------------------------------------------------ /\x{10ffff}/8BM Memory allocation (code space): 12 ------------------------------------------------------------------ 0 8 Bra 3 \x{10ffff} 8 8 Ket 11 End ------------------------------------------------------------------ /\x{110000}/8BM Failed: character value in \x{...} sequence is too large at offset 9 /[\x{ff}]/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 \x{ff} 6 6 Ket 9 End ------------------------------------------------------------------ /[\x{100}]/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 \x{100} 6 6 Ket 9 End ------------------------------------------------------------------ /\x80/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 \x{80} 6 6 Ket 9 End ------------------------------------------------------------------ /\xff/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 \x{ff} 6 6 Ket 9 End ------------------------------------------------------------------ /\x{0041}\x{2262}\x{0391}\x{002e}/D8M Memory allocation (code space): 18 ------------------------------------------------------------------ 0 14 Bra 3 A\x{2262}\x{391}. 14 14 Ket 17 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = 'A' Need char = '.' /\x{D55c}\x{ad6d}\x{C5B4}/D8M Memory allocation (code space): 19 ------------------------------------------------------------------ 0 15 Bra 3 \x{d55c}\x{ad6d}\x{c5b4} 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{ed} Need char = \x{b4} /\x{65e5}\x{672c}\x{8a9e}/D8M Memory allocation (code space): 19 ------------------------------------------------------------------ 0 15 Bra 3 \x{65e5}\x{672c}\x{8a9e} 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf First char = \x{e6} Need char = \x{9e} /[\x{100}]/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 \x{100} 6 6 Ket 9 End ------------------------------------------------------------------ /[Z\x{100}]/8BM Memory allocation (code space): 47 ------------------------------------------------------------------ 0 43 Bra 3 [Z\x{100}] 43 43 Ket 46 End ------------------------------------------------------------------ /^[\x{100}\E-\Q\E\x{150}]/B8M Memory allocation (code space): 18 ------------------------------------------------------------------ 0 14 Bra 3 ^ 4 [\x{100}-\x{150}] 14 14 Ket 17 End ------------------------------------------------------------------ /^[\QÄ€\E-\QÅ\E]/B8M Memory allocation (code space): 18 ------------------------------------------------------------------ 0 14 Bra 3 ^ 4 [\x{100}-\x{150}] 14 14 Ket 17 End ------------------------------------------------------------------ /^[\QÄ€\E-\QÅ\E/B8M Failed: missing terminating ] for character class at offset 15 /[\p{L}]/BM Memory allocation (code space): 15 ------------------------------------------------------------------ 0 11 Bra 3 [\p{L}] 11 11 Ket 14 End ------------------------------------------------------------------ /[\p{^L}]/BM Memory allocation (code space): 15 ------------------------------------------------------------------ 0 11 Bra 3 [\P{L}] 11 11 Ket 14 End ------------------------------------------------------------------ /[\P{L}]/BM Memory allocation (code space): 15 ------------------------------------------------------------------ 0 11 Bra 3 [\P{L}] 11 11 Ket 14 End ------------------------------------------------------------------ /[\P{^L}]/BM Memory allocation (code space): 15 ------------------------------------------------------------------ 0 11 Bra 3 [\p{L}] 11 11 Ket 14 End ------------------------------------------------------------------ /[abc\p{L}\x{0660}]/8BM Memory allocation (code space): 50 ------------------------------------------------------------------ 0 46 Bra 3 [a-c\p{L}\x{660}] 46 46 Ket 49 End ------------------------------------------------------------------ /[\p{Nd}]/8BM Memory allocation (code space): 15 ------------------------------------------------------------------ 0 11 Bra 3 [\p{Nd}] 11 11 Ket 14 End ------------------------------------------------------------------ /[\p{Nd}+-]+/8BM Memory allocation (code space): 48 ------------------------------------------------------------------ 0 44 Bra 3 [+\-\p{Nd}]+ 44 44 Ket 47 End ------------------------------------------------------------------ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM Memory allocation (code space): 25 ------------------------------------------------------------------ 0 21 Bra 3 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} 21 21 Ket 24 End ------------------------------------------------------------------ /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM Memory allocation (code space): 25 ------------------------------------------------------------------ 0 21 Bra 3 A\x{391}\x{10427}\x{ff3a}\x{1fb0} 21 21 Ket 24 End ------------------------------------------------------------------ /[\x{105}-\x{109}]/8iBM Memory allocation (code space): 17 ------------------------------------------------------------------ 0 13 Bra 3 [\x{104}-\x{109}] 13 13 Ket 16 End ------------------------------------------------------------------ /( ( (?(1)0|) )* )/xBM Memory allocation (code space): 38 ------------------------------------------------------------------ 0 34 Bra 3 28 CBra 1 8 Brazero 9 19 SCBra 2 14 8 Cond 17 1 Cond ref 20 0 22 3 Alt 25 11 Ket 28 19 KetRmax 31 28 Ket 34 34 Ket 37 End ------------------------------------------------------------------ /( (?(1)0|)* )/xBM Memory allocation (code space): 30 ------------------------------------------------------------------ 0 26 Bra 3 20 CBra 1 8 Brazero 9 8 SCond 12 1 Cond ref 15 0 17 3 Alt 20 11 KetRmax 23 20 Ket 26 26 Ket 29 End ------------------------------------------------------------------ /[a]/BM Memory allocation (code space): 9 ------------------------------------------------------------------ 0 5 Bra 3 a 5 5 Ket 8 End ------------------------------------------------------------------ /[a]/8BM Memory allocation (code space): 9 ------------------------------------------------------------------ 0 5 Bra 3 a 5 5 Ket 8 End ------------------------------------------------------------------ /[\xaa]/BM Memory allocation (code space): 9 ------------------------------------------------------------------ 0 5 Bra 3 \xaa 5 5 Ket 8 End ------------------------------------------------------------------ /[\xaa]/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 \x{aa} 6 6 Ket 9 End ------------------------------------------------------------------ /[^a]/BM Memory allocation (code space): 9 ------------------------------------------------------------------ 0 5 Bra 3 [^a] 5 5 Ket 8 End ------------------------------------------------------------------ /[^a]/8BM Memory allocation (code space): 9 ------------------------------------------------------------------ 0 5 Bra 3 [^a] 5 5 Ket 8 End ------------------------------------------------------------------ /[^\xaa]/BM Memory allocation (code space): 9 ------------------------------------------------------------------ 0 5 Bra 3 [^\xaa] 5 5 Ket 8 End ------------------------------------------------------------------ /[^\xaa]/8BM Memory allocation (code space): 10 ------------------------------------------------------------------ 0 6 Bra 3 [^\x{aa}] 6 6 Ket 9 End ------------------------------------------------------------------ /[^\d]/8WB ------------------------------------------------------------------ 0 11 Bra 3 [^\p{Nd}] 11 11 Ket 14 End ------------------------------------------------------------------ /[[:^alpha:][:^cntrl:]]+/8WB ------------------------------------------------------------------ 0 44 Bra 3 [ -~\x80-\xff\P{L}]+ 44 44 Ket 47 End ------------------------------------------------------------------ /[[:^cntrl:][:^alpha:]]+/8WB ------------------------------------------------------------------ 0 44 Bra 3 [ -~\x80-\xff\P{L}]+ 44 44 Ket 47 End ------------------------------------------------------------------ /[[:alpha:]]+/8WB ------------------------------------------------------------------ 0 12 Bra 3 [\p{L}]+ 12 12 Ket 15 End ------------------------------------------------------------------ /[[:^alpha:]\S]+/8WB ------------------------------------------------------------------ 0 15 Bra 3 [\P{L}\P{Xsp}]+ 15 15 Ket 18 End ------------------------------------------------------------------ /abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B ------------------------------------------------------------------ 0 73 Bra 3 abc 9 7 CBra 1 14 d 16 5 Alt 19 e 21 12 Ket 24 *THEN 25 x 27 14 CBra 2 32 123 38 *THEN 39 4 41 29 Alt 44 567 50 7 CBra 3 55 b 57 5 Alt 60 q 62 12 Ket 65 *THEN 66 xx 70 43 Ket 73 73 Ket 76 End ------------------------------------------------------------------ /-- End of testinput11 --/ pcre-8.31/testdata/testinput10000644000222100022210000026411011767143677013206 00000000000000/-- This set of tests is for features that are compatible with all versions of Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and 16-bit PCRE libraries. --/ /the quick brown fox/ the quick brown fox The quick brown FOX What do you know about the quick brown fox? What do you know about THE QUICK BROWN FOX? /The quick brown fox/i the quick brown fox The quick brown FOX What do you know about the quick brown fox? What do you know about THE QUICK BROWN FOX? /abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ abcd\t\n\r\f\a\e9;\$\\?caxyz /a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ abxyzpqrrrabbxyyyypqAzz abxyzpqrrrabbxyyyypqAzz aabxyzpqrrrabbxyyyypqAzz aaabxyzpqrrrabbxyyyypqAzz aaaabxyzpqrrrabbxyyyypqAzz abcxyzpqrrrabbxyyyypqAzz aabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypAzz aaabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypqqAzz aaabcxyzpqrrrabbxyyyypqqqAzz aaabcxyzpqrrrabbxyyyypqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqqAzz aaaabcxyzpqrrrabbxyyyypqAzz abxyzzpqrrrabbxyyyypqAzz aabxyzzzpqrrrabbxyyyypqAzz aaabxyzzzzpqrrrabbxyyyypqAzz aaaabxyzzzzpqrrrabbxyyyypqAzz abcxyzzpqrrrabbxyyyypqAzz aabcxyzzzpqrrrabbxyyyypqAzz aaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyyypqAzz aaabcxyzpqrrrabbxyyyypABzz aaabcxyzpqrrrabbxyyyypABBzz >>>aaabxyzpqrrrabbxyyyypqAzz >aaaabxyzpqrrrabbxyyyypqAzz >>>>abcxyzpqrrrabbxyyyypqAzz *** Failers abxyzpqrrabbxyyyypqAzz abxyzpqrrrrabbxyyyypqAzz abxyzpqrrrabxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyypqAzz aaabcxyzpqrrrabbxyyyypqqqqqqqAzz /^(abc){1,2}zz/ abczz abcabczz *** Failers zz abcabcabczz >>abczz /^(b+?|a){1,2}?c/ bc bbc bbbc bac bbac aac abbbbbbbbbbbc bbbbbbbbbbbac *** Failers aaac abbbbbbbbbbbac /^(b+|a){1,2}c/ bc bbc bbbc bac bbac aac abbbbbbbbbbbc bbbbbbbbbbbac *** Failers aaac abbbbbbbbbbbac /^(b+|a){1,2}?bc/ bbc /^(b*|ba){1,2}?bc/ babc bbabc bababc *** Failers bababbc babababc /^(ba|b*){1,2}?bc/ babc bbabc bababc *** Failers bababbc babababc /^\ca\cA\c[\c{\c:/ \x01\x01\e;z /^[ab\]cde]/ athing bthing ]thing cthing dthing ething *** Failers fthing [thing \\thing /^[]cde]/ ]thing cthing dthing ething *** Failers athing fthing /^[^ab\]cde]/ fthing [thing \\thing *** Failers athing bthing ]thing cthing dthing ething /^[^]cde]/ athing fthing *** Failers ]thing cthing dthing ething /^\/ /^ÿ/ ÿ /^[0-9]+$/ 0 1 2 3 4 5 6 7 8 9 10 100 *** Failers abc /^.*nter/ enter inter uponter /^xxx[0-9]+$/ xxx0 xxx1234 *** Failers xxx /^.+[0-9][0-9][0-9]$/ x123 xx123 123456 *** Failers 123 x1234 /^.+?[0-9][0-9][0-9]$/ x123 xx123 123456 *** Failers 123 x1234 /^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ abc!pqr=apquxz.ixr.zzz.ac.uk *** Failers !pqr=apquxz.ixr.zzz.ac.uk abc!=apquxz.ixr.zzz.ac.uk abc!pqr=apquxz:ixr.zzz.ac.uk abc!pqr=apquxz.ixr.zzz.ac.ukk /:/ Well, we need a colon: somewhere *** Fail if we don't /([\da-f:]+)$/i 0abc abc fed E :: 5f03:12C0::932e fed def Any old stuff *** Failers 0zzz gzzz fed\x20 Any old rubbish /^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ .1.2.3 A.12.123.0 *** Failers .1.2.3333 1.2.3 1234.2.3 /^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ 1 IN SOA non-sp1 non-sp2( 1 IN SOA non-sp1 non-sp2 ( *** Failers 1IN SOA non-sp1 non-sp2( /^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ a. Z. 2. ab-c.pq-r. sxk.zzz.ac.uk. x-.y-. *** Failers -abc.peq. /^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ *.a *.b0-a *.c3-b.c *.c-a.b-c *** Failers *.0 *.a- *.a-b.c- *.c-a.0-c /^(?=ab(de))(abd)(e)/ abde /^(?!(ab)de|x)(abd)(f)/ abdf /^(?=(ab(cd)))(ab)/ abcd /^[\da-f](\.[\da-f])*$/i a.b.c.d A.B.C.D a.b.c.1.2.3.C /^\".*\"\s*(;.*)?$/ \"1234\" \"abcd\" ; \"\" ; rhubarb *** Failers \"1234\" : things /^$/ \ *** Failers / ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x ab c *** Failers abc ab cde /(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ ab c *** Failers abc ab cde /^ a\ b[c ]d $/x a bcd a b d *** Failers abcd ab d /^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ abcdefhijklm /^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ abcdefhijklm /^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ a+ Z0+\x08\n\x1d\x12 /^[.^$|()*+?{,}]+/ .^\$(*+)|{?,?} /^a*\w/ z az aaaz a aa aaaa a+ aa+ /^a*?\w/ z az aaaz a aa aaaa a+ aa+ /^a+\w/ az aaaz aa aaaa aa+ /^a+?\w/ az aaaz aa aaaa aa+ /^\d{8}\w{2,}/ 1234567890 12345678ab 12345678__ *** Failers 1234567 /^[aeiou\d]{4,5}$/ uoie 1234 12345 aaaaa *** Failers 123456 /^[aeiou\d]{4,5}?/ uoie 1234 12345 aaaaa 123456 /\A(abc|def)=(\1){2,3}\Z/ abc=abcabc def=defdefdef *** Failers abc=defdef /^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ abcdefghijkcda2 abcdefghijkkkkcda2 /(cat(a(ract|tonic)|erpillar)) \1()2(3)/ cataract cataract23 catatonic catatonic23 caterpillar caterpillar23 /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ From abcd Mon Sep 01 12:33:02 1997 /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ From abcd Mon Sep 01 12:33:02 1997 From abcd Mon Sep 1 12:33:02 1997 *** Failers From abcd Sep 01 12:33:02 1997 /^12.34/s 12\n34 12\r34 /\w+(?=\t)/ the quick brown\t fox /foo(?!bar)(.*)/ foobar is foolish see? /(?:(?!foo)...|^.{0,2})bar(.*)/ foobar crowbar etc barrel 2barrel A barrel /^(\D*)(?=\d)(?!123)/ abc456 *** Failers abc123 /^1234(?# test newlines inside)/ 1234 /^1234 #comment in extended re /x 1234 /#rhubarb abcd/x abcd /^abcd#rhubarb/x abcd /^(a)\1{2,3}(.)/ aaab aaaab aaaaab aaaaaab /(?!^)abc/ the abc *** Failers abc /(?=^)abc/ abc *** Failers the abc /^[ab]{1,3}(ab*|b)/ aabbbbb /^[ab]{1,3}?(ab*|b)/ aabbbbb /^[ab]{1,3}?(ab*?|b)/ aabbbbb /^[ab]{1,3}(ab*?|b)/ aabbbbb / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /x Alan Other user\@dom.ain \"A. Other\" (a comment) A. Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) # leading word [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces (?: (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) | " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " ) # "special" comment or quoted string [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" )* < [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # < (?: @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* (?: , [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* )* # additional domains : [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address spec > # > # name and address ) /x Alan Other user\@dom.ain \"A. Other\" (a comment) A. Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay A missing angle ]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is 43.
Word Processor
(N-1286)
Lega lstaff.comCA - Statewide /a[^a]b/ acb a\nb /a.b/ acb *** Failers a\nb /a[^a]b/s acb a\nb /a.b/s acb a\nb /^(b+?|a){1,2}?c/ bac bbac bbbac bbbbac bbbbbac /^(b+|a){1,2}?c/ bac bbac bbbac bbbbac bbbbbac /(?!\A)x/m x\nb\n a\bx\n /\x0{ab}/ \0{ab} /(A|B)*?CD/ CD /(A|B)*CD/ CD /(AB)*?\1/ ABABAB /(AB)*\1/ ABABAB /(?.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ "(?>.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo /(?>(\.\d\d[1-9]?))\d+/ 1.230003938 1.875000282 *** Failers 1.235 /^((?>\w+)|(?>\s+))*$/ now is the time for all good men to come to the aid of the party *** Failers this is not a line with only words and spaces! /(\d+)(\w)/ 12345a 12345+ /((?>\d+))(\w)/ 12345a *** Failers 12345+ /(?>a+)b/ aaab /((?>a+)b)/ aaab /(?>(a+))b/ aaab /(?>b)+/ aaabbbccc /(?>a+|b+|c+)*c/ aaabbbbccccd /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x /\(((?>[^()]+)|\([^()]+\))+\)/ (abc) (abc(def)xyz) *** Failers ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /a(?-i)b/i ab Ab *** Failers aB AB /(a (?x)b c)d e/ a bcd e *** Failers a b cd e abcd e a bcde /(a b(?x)c d (?-x)e f)/ a bcde f *** Failers abcdef /(a(?i)b)c/ abc aBc *** Failers abC aBC Abc ABc ABC AbC /a(?i:b)c/ abc aBc *** Failers ABC abC aBC /a(?i:b)*c/ aBc aBBc *** Failers aBC aBBC /a(?=b(?i)c)\w\wd/ abcd abCd *** Failers aBCd abcD /(?s-i:more.*than).*million/i more than million more than MILLION more \n than Million *** Failers MORE THAN MILLION more \n than \n million /(?:(?s-i)more.*than).*million/i more than million more than MILLION more \n than Million *** Failers MORE THAN MILLION more \n than \n million /(?>a(?i)b+)+c/ abc aBbc aBBc *** Failers Abc abAb abbC /(?=a(?i)b)\w\wc/ abc aBc *** Failers Ab abC aBC /(?<=a(?i)b)(\w\w)c/ abxxc aBxxc *** Failers Abxxc ABxxc abxxC /(?:(a)|b)(?(1)A|B)/ aA bB *** Failers aB bA /^(a)?(?(1)a|b)+$/ aa b bb *** Failers ab /^(?(?=abc)\w{3}:|\d\d)$/ abc: 12 *** Failers 123 xyz /^(?(?!abc)\d\d|\w{3}:)$/ abc: 12 *** Failers 123 xyz /(?(?<=foo)bar|cat)/ foobar cat fcat focat *** Failers foocat /(?(?a*)*/ a aa aaaa /(abc|)+/ abc abcabc abcabcabc xyz /([a]*)*/ a aaaaa /([ab]*)*/ a b ababab aaaabcde bbbb /([^a]*)*/ b bbbb aaa /([^ab]*)*/ cccc abab /([a]*?)*/ a aaaa /([ab]*?)*/ a b abab baba /([^a]*?)*/ b bbbb aaa /([^ab]*?)*/ c cccc baba /(?>a*)*/ a aaabcde /((?>a*))*/ aaaaa aabbaa /((?>a*?))*/ aaaaa aabbaa /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x 12-sep-98 12-09-98 *** Failers sep-12-98 /(?<=(foo))bar\1/ foobarfoo foobarfootling *** Failers foobar barfoo /(?i:saturday|sunday)/ saturday sunday Saturday Sunday SATURDAY SUNDAY SunDay /(a(?i)bc|BB)x/ abcx aBCx bbx BBx *** Failers abcX aBCX bbX BBX /^([ab](?i)[cd]|[ef])/ ac aC bD elephant Europe frog France *** Failers Africa /^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ ab aBd xy xY zebra Zambesi *** Failers aCD XY /(?<=foo\n)^bar/m foo\nbar *** Failers bar baz\nbar /(?<=(?]&/ <&OUT /^(a\1?){4}$/ aaaaaaaaaa *** Failers AB aaaaaaaaa aaaaaaaaaaa /^(a(?(1)\1)){4}$/ aaaaaaaaaa *** Failers aaaaaaaaa aaaaaaaaaaa /(?:(f)(o)(o)|(b)(a)(r))*/ foobar /(?<=a)b/ ab *** Failers cb b /(?a+)ab/ /(?>a+)b/ aaab /([[:]+)/ a:[b]: /([[=]+)/ a=[b]= /([[.]+)/ a.[b]. /((?>a+)b)/ aaab /(?>(a+))b/ aaab /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x /a\Z/ *** Failers aaab a\nb\n /b\Z/ a\nb\n /b\z/ /b\Z/ a\nb /b\z/ a\nb *** Failers /^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ a abc a-b 0-9 a.b 5.6.7 the.quick.brown.fox a100.b200.300c 12-ab.1245 *** Failers \ .a -a a- a. a_b a.- a.. ab..bc the.quick.brown.fox- the.quick.brown.fox. the.quick.brown.fox_ the.quick.brown.fox+ /(?>.*)(?<=(abcd|wxyz))/ alphabetabcd endingwxyz *** Failers a rather long string that doesn't end with one of them /word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark /word (?>[a-zA-Z0-9]+ ){0,30}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope /(?<=\d{3}(?!999))foo/ 999foo 123999foo *** Failers 123abcfoo /(?<=(?!...999)\d{3})foo/ 999foo 123999foo *** Failers 123abcfoo /(?<=\d{3}(?!999)...)foo/ 123abcfoo 123456foo *** Failers 123999foo /(?<=\d{3}...)(?\s*)=(?>\s*) # find Z)+|A)*/ ZABCDEFG /((?>)+|A)*/ ZABCDEFG /a*/g abbab /^[a-\d]/ abcde -things 0digit *** Failers bcdef /^[\d-a]/ abcde -things 0digit *** Failers bcdef /[[:space:]]+/ > \x09\x0a\x0c\x0d\x0b< /[[:blank:]]+/ > \x09\x0a\x0c\x0d\x0b< /[\s]+/ > \x09\x0a\x0c\x0d\x0b< /\s+/ > \x09\x0a\x0c\x0d\x0b< /a b/x ab /(?!\A)x/m a\nxb\n /(?!^)x/m a\nxb\n /abc\Qabc\Eabc/ abcabcabc /abc\Q(*+|\Eabc/ abc(*+|abc / abc\Q abc\Eabc/x abc abcabc *** Failers abcabcabc /abc#comment \Q#not comment literal\E/x abc#not comment\n literal /abc#comment \Q#not comment literal/x abc#not comment\n literal /abc#comment \Q#not comment literal\E #more comment /x abc#not comment\n literal /abc#comment \Q#not comment literal\E #more comment/x abc#not comment\n literal /\Qabc\$xyz\E/ abc\\\$xyz /\Qabc\E\$\Qxyz\E/ abc\$xyz /\Gabc/ abc *** Failers xyzabc /\Gabc./g abc1abc2xyzabc3 /abc./g abc1abc2xyzabc3 /a(?x: b c )d/ XabcdY *** Failers Xa b c d Y /((?x)x y z | a b c)/ XabcY AxyzB /(?i)AB(?-i)C/ XabCY *** Failers XabcY /((?i)AB(?-i)C|D)E/ abCE DE *** Failers abcE abCe dE De /(.*)\d+\1/ abc123abc abc123bc /(.*)\d+\1/s abc123abc abc123bc /((.*))\d+\1/ abc123abc abc123bc /-- This tests for an IPv6 address in the form where it can have up to --/ /-- eight components, one and only one of which is empty. This must be --/ /-- an internal component. --/ /^(?!:) # colon disallowed at start (?: # start of item (?: [0-9a-f]{1,4} | # 1-4 hex digits or (?(1)0 | () ) ) # if null previously matched, fail; else null : # followed by colon ){1,7} # end item; 1-7 of them required [0-9a-f]{1,4} $ # final hex number at end of string (?(1)|.) # check that there was an empty component /xi a123::a123 a123:b342::abcd a123:b342::324e:abcd a123:ddde:b342::324e:abcd a123:ddde:b342::324e:dcba:abcd a123:ddde:9999:b342::324e:dcba:abcd *** Failers 1:2:3:4:5:6:7:8 a123:bce:ddde:9999:b342::324e:dcba:abcd a123::9999:b342::324e:dcba:abcd abcde:2:3:4:5:6:7:8 ::1 abcd:fee0:123:: :1 1: /[z\Qa-d]\E]/ z a - d ] *** Failers b /[\z\C]/ z C /\M/ M /(a+)*b/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /(?i)reg(?:ul(?:[aä]|ae)r|ex)/ REGular regulaer Regex regulär /Åæåä[à-ÿÀ-ß]+/ Åæåäà Åæåäÿ ÅæåäÀ Åæåäß /(?<=Z)X./ \x84XAZXB /ab cd (?x) de fg/ ab cd defg /ab cd(?x) de fg/ ab cddefg ** Failers abcddefg /(?a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /(?:a|)*\d/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 /\Z/g abc\n /^(?s)(?>.*)(?(a))b|(a)c/ ac /(?=(a))ab|(a)c/ ac /((?>(a))b|(a)c)/ ac /((?>(a))b|(a)c)++/ ac /(?:(?>(a))b|(a)c)++/ ac /(?=(?>(a))b|(a)c)(..)/ ac /(?>(?>(a))b|(a)c)/ ac /(?:(?>([ab])))+a=/+ =ba= /(?>([ab]))+a=/+ =ba= /((?>(a+)b)+(aabab))/ aaaabaaabaabab /(?>a+|ab)+?c/ aabc /(?>a+|ab)+c/ aabc /(?:a+|ab)+c/ aabc /(?(?=(a))a)/ a /(?(?=(a))a)(b)/ ab /^(?:a|ab)++c/ aaaabc /^(?>a|ab)++c/ aaaabc /^(?:a|ab)+c/ aaaabc /(?=abc){3}abc/+ abcabcabc ** Failers xyz /(?=abc)+abc/+ abcabcabc ** Failers xyz /(?=abc)++abc/+ abcabcabc ** Failers xyz /(?=abc){0}xyz/ xyz /(?=abc){1}xyz/ ** Failers xyz /(?=(a))?./ ab bc /(?=(a))??./ ab bc /^(?=(a)){0}b(?1)/ backgammon /^(?=(?1))?[az]([abc])d/ abd zcdxx /^(?!a){0}\w+/ aaaaa /(?<=(abc))?xyz/ abcxyz pqrxyz /^[\g]+/ ggg<<>> ** Failers \\ga /^[\ga]+/ gggagagaxyz /^[:a[:digit:]]+/ aaaa444:::Z /^[:a[:digit:]:b]+/ aaaa444:::bbbZ /[:a]xxx[b:]/ :xxx: /(?<=a{2})b/i xaabc ** Failers xabc /(?XNNNYZ > X NYQZ ** Failers >XYZ > X NY Z /\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ >XY\x0aZ\x0aA\x0bNN\x0c >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c /(foo)\Kbar/ foobar /(foo)(\Kbar|baz)/ foobar foobaz /(foo\Kbar)baz/ foobarbaz /abc\K|def\K/g+ Xabcdefghi /ab\Kc|de\Kf/g+ Xabcdefghi /(?=C)/g+ ABCDECBA /^abc\K/+ abcdef ** Failers defabcxyz /^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ ababababbbabZXXXX /(?tom|bon)-\g{A}/ tom-tom bon-bon /(^(a|b\g{-1}))/ bacxxx /(?|(abc)|(xyz))\1/ abcabc xyzxyz ** Failers abcxyz xyzabc /(?|(abc)|(xyz))(?1)/ abcabc xyzabc ** Failers xyzxyz /^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ XYabcdY /^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ XYabcdY /^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ XYabcdY /(?'abc'\w+):\k{2}/ a:aaxyz ab:ababxyz ** Failers a:axyz ab:abxyz /(?'abc'\w+):\g{abc}{2}/ a:aaxyz ab:ababxyz ** Failers a:axyz ab:abxyz /^(?a)? (?()b|c) (?('ab')d|e)/x abd ce /^(a.)\g-1Z/ aXaXZ /^(a.)\g{-1}Z/ aXaXZ /^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x abcd /(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) (?(DEFINE) (?[a-z]+) (?\d+) )/x metcalfe 33 /(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ 1.2.3.4 131.111.10.206 10.0.0.0 ** Failers 10.6 455.3.4.5 /\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ 1.2.3.4 131.111.10.206 10.0.0.0 ** Failers 10.6 455.3.4.5 /^(\w++|\s++)*$/ now is the time for all good men to come to the aid of the party *** Failers this is not a line with only words and spaces! /(\d++)(\w)/ 12345a *** Failers 12345+ /a++b/ aaab /(a++b)/ aaab /(a++)b/ aaab /([^()]++|\([^()]*\))+/ ((abc(ade)ufh()()x /\(([^()]++|\([^()]+\))+\)/ (abc) (abc(def)xyz) *** Failers ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /^([^()]|\((?1)*\))*$/ abc a(b)c a(b(c))d *** Failers) a(b(c)d /^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/x <> hij> hij> def> *** Failers a)(?<=b(?&X))/ baz /^(?|(abc)|(def))\1/ abcabc defdef ** Failers abcdef defabc /^(?|(abc)|(def))(?1)/ abcabc defabc ** Failers defdef abcdef /(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ a\"aaaaa b\"aaaaa ** Failers b\"11111 /(?:(?1)|B)(A(*F)|C)/ ABCD CCD ** Failers CAD /^(?:(?1)|B)(A(*F)|C)/ CCD BCD ** Failers ABCD CAD BAD /(?:(?1)|B)(A(*ACCEPT)XX|C)D/ AAD ACD BAD BCD BAX ** Failers ACX ABC /(?(DEFINE)(A))B(?1)C/ BAC /(?(DEFINE)((A)\2))B(?1)C/ BAAC /(? \( ( [^()]++ | (?&pn) )* \) )/x (ab(cd)ef) /^(?!a(*SKIP)b)/ ac /^(?=a(*SKIP)b|ac)/ ** Failers ac /^(?=a(*THEN)b|ac)/ ac /^(?=a(*PRUNE)b)/ ab ** Failers ac /^(?=a(*ACCEPT)b)/ ac /^(?(?!a(*SKIP)b))/ ac /(?>a\Kb)/ ab /((?>a\Kb))/ ab /(a\Kb)/ ab /^a\Kcz|ac/ ac /(?>a\Kbz|ab)/ ab /^(?&t)(?(DEFINE)(?a\Kb))$/ ab /^([^()]|\((?1)*\))*$/ a(b)c a(b(c)d)e /(?P(?P0)(?P>L1)|(?P>L2))/ 0 00 0000 /(?P(?P0)|(?P>L2)(?P>L1))/ 0 00 0000 /--- This one does fail, as expected, in Perl. It needs the complex item at the end of the pattern. A single letter instead of (B|D) makes it not fail, which I think is a Perl bug. --- / /A(*COMMIT)(B|D)/ ACABX /--- Check the use of names for failure ---/ /^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K ** Failers AC CB /--- Force no study, otherwise mark is not seen. The studied version is in test 2 because it isn't Perl-compatible. ---/ /(*MARK:A)(*SKIP:B)(C|X)/KSS C D /^(A(*THEN:A)B|C(*THEN:B)D)/K ** Failers CB /^(?:A(*THEN:A)B|C(*THEN:B)D)/K CB /^(?>A(*THEN:A)B|C(*THEN:B)D)/K CB /--- This should succeed, as the skip causes bump to offset 1 (the mark). Note that we have to have something complicated such as (B|Z) at the end because, for Perl, a simple character somehow causes an unwanted optimization to mess with the handling of backtracking verbs. ---/ /A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC /--- Test skipping over a non-matching mark. ---/ /A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK AAAC /--- Check shorthand for MARK ---/ /A(*:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC /--- Don't loop! Force no study, otherwise mark is not seen. ---/ /(*:A)A+(*SKIP:A)(B|Z)/KSS AAAC /--- This should succeed, as a non-existent skip name disables the skip ---/ /A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK AAAC /A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK AAAC /--- COMMIT at the start of a pattern should act like an anchor. Again, however, we need the complication for Perl. ---/ /(*COMMIT)(A|P)(B|P)(C|P)/ ABCDEFG ** Failers DEFGABC /--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ /(\w+)(?>b(*COMMIT))\w{2}/ abbb /(\w+)b(*COMMIT)\w{2}/ abbb /--- Check opening parens in comment when seeking forward reference. ---/ /(?&t)(?#()(?(DEFINE)(?a))/ bac /--- COMMIT should override THEN ---/ /(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ yes /(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ yes /b?(*SKIP)c/ bc abc /(*SKIP)bc/ a /(*SKIP)b/ a /(?P(?P=abn)xxx|)+/ xxx /(?i:([^b]))(?1)/ aa aA ** Failers ab aB Ba ba /^(?&t)*+(?(DEFINE)(?a))\w$/ aaaaaaX ** Failers aaaaaa /^(?&t)*(?(DEFINE)(?a))\w$/ aaaaaaX aaaaaa /^(a)*+(\w)/ aaaaX YZ ** Failers aaaa /^(?:a)*+(\w)/ aaaaX YZ ** Failers aaaa /^(a)++(\w)/ aaaaX ** Failers aaaa YZ /^(?:a)++(\w)/ aaaaX ** Failers aaaa YZ /^(a)?+(\w)/ aaaaX YZ /^(?:a)?+(\w)/ aaaaX YZ /^(a){2,}+(\w)/ aaaaX ** Failers aaa YZ /^(?:a){2,}+(\w)/ aaaaX ** Failers aaa YZ /(a|)*(?1)b/ b ab aab /(a)++(?1)b/ ** Failers ab aab /(a)*+(?1)b/ ** Failers ab aab /(?1)(?:(b)){0}/ b /(foo ( \( ((?:(?> [^()]+ )|(?2))*) \) ) )/x foo(bar(baz)+baz(bop)) /(A (A|B(*ACCEPT)|C) D)(E)/x AB /\A.*?(?:a|b(*THEN)c)/ ba /\A.*?(?:a|bc)/ ba /\A.*?(a|b(*THEN)c)/ ba /\A.*?(a|bc)/ ba /\A.*?(?:a|b(*THEN)c)++/ ba /\A.*?(?:a|bc)++/ ba /\A.*?(a|b(*THEN)c)++/ ba /\A.*?(a|bc)++/ ba /\A.*?(?:a|b(*THEN)c|d)/ ba /\A.*?(?:a|bc|d)/ ba /(?:(b))++/ beetle /(?(?=(a(*ACCEPT)z))a)/ a /^(a)(?1)+ab/ aaaab /^(a)(?1)++ab/ aaaab /^(?=a(*:M))aZ/K aZbc /^(?!(*:M)b)aZ/K aZbc /(?(DEFINE)(a))?b(?1)/ backgammon /^\N+/ abc\ndef /^\N{1,}/ abc\ndef /(?(R)a+|(?R)b)/ aaaabcde /(?(R)a+|((?R))b)/ aaaabcde /((?(R)a+|(?1)b))/ aaaabcde /((?(R1)a+|(?1)b))/ aaaabcde /a(*:any name)/K abc /(?>(?&t)c|(?&t))(?(DEFINE)(?a|b(*PRUNE)c))/ a ba bba /--- Checking revised (*THEN) handling ---/ /--- Capture ---/ /^.*? (a(*THEN)b) c/x aabc /^.*? (a(*THEN)b|(*F)) c/x aabc /^.*? ( (a(*THEN)b) | (*F) ) c/x aabc /^.*? ( (a(*THEN)b) ) c/x aabc /--- Non-capture ---/ /^.*? (?:a(*THEN)b) c/x aabc /^.*? (?:a(*THEN)b|(*F)) c/x aabc /^.*? (?: (?:a(*THEN)b) | (*F) ) c/x aabc /^.*? (?: (?:a(*THEN)b) ) c/x aabc /--- Atomic ---/ /^.*? (?>a(*THEN)b) c/x aabc /^.*? (?>a(*THEN)b|(*F)) c/x aabc /^.*? (?> (?>a(*THEN)b) | (*F) ) c/x aabc /^.*? (?> (?>a(*THEN)b) ) c/x aabc /--- Possessive capture ---/ /^.*? (a(*THEN)b)++ c/x aabc /^.*? (a(*THEN)b|(*F))++ c/x aabc /^.*? ( (a(*THEN)b)++ | (*F) )++ c/x aabc /^.*? ( (a(*THEN)b)++ )++ c/x aabc /--- Possessive non-capture ---/ /^.*? (?:a(*THEN)b)++ c/x aabc /^.*? (?:a(*THEN)b|(*F))++ c/x aabc /^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c/x aabc /^.*? (?: (?:a(*THEN)b)++ )++ c/x aabc /--- Condition assertion ---/ /^(?(?=a(*THEN)b)ab|ac)/ ac /--- Condition ---/ /^.*?(?(?=a)a|b(*THEN)c)/ ba /^.*?(?:(?(?=a)a|b(*THEN)c)|d)/ ba /^.*?(?(?=a)a(*THEN)b|c)/ ac /--- Assertion ---/ /^.*(?=a(*THEN)b)/ aabc /------------------------------/ /(?>a(*:m))/imsxSK a /(?>(a)(*:m))/imsxSK a /(?<=a(*ACCEPT)b)c/ xacd /(?<=(a(*ACCEPT)b))c/ xacd /(?<=(a(*COMMIT)b))c/ xabcd ** Failers xacd /(?a?)*)*c/ aac /-- End of testinput1 --/ pcre-8.31/testdata/testinput20000644000222100022210000017017411767404630013202 00000000000000/-- This set of tests is not Perl-compatible. It checks on special features of PCRE's API, error diagnostics, and the compiled code of some patterns. It also checks the non-Perl syntax the PCRE supports (Python, .NET, Oniguruma). Finally, there are some tests where PCRE and Perl differ, either because PCRE can't be compatible, or there is a possible Perl bug. NOTE: This is a non-UTF set of tests. When UTF support is needed, use test 5, and if Unicode Property Support is needed, use test 7. --/ /(a)b|/I /abc/I abc defabc \Aabc *** Failers \Adefabc ABC /^abc/I abc \Aabc *** Failers defabc \Adefabc /a+bc/I /a*bc/I /a{3}bc/I /(abc|a+z)/I /^abc$/I abc *** Failers def\nabc /ab\idef/X /(?X)ab\idef/X /x{5,4}/ /z{65536}/ /[abcd/ /(?X)[\B]/ /(?X)[\R]/ /(?X)[\X]/ /[\B]/BZ /[\R]/BZ /[\X]/BZ /[z-a]/ /^*/ /(abc/ /(?# abc/ /(?z)abc/ /.*b/I /.*?b/I /cat|dog|elephant/I this sentence eventually mentions a cat this sentences rambles on and on for a while and then reaches elephant /cat|dog|elephant/IS this sentence eventually mentions a cat this sentences rambles on and on for a while and then reaches elephant /cat|dog|elephant/IiS this sentence eventually mentions a CAT cat this sentences rambles on and on for a while to elephant ElePhant /a|[bcd]/IS /(a|[^\dZ])/IS /(a|b)*[\s]/IS /(ab\2)/ /{4,5}abc/ /(a)(b)(c)\2/I abcb \O0abcb \O3abcb \O6abcb \O9abcb \O12abcb /(a)bc|(a)(b)\2/I abc \O0abc \O3abc \O6abc aba \O0aba \O3aba \O6aba \O9aba \O12aba /abc$/IE abc *** Failers abc\n abc\ndef /(a)(b)(c)(d)(e)\6/ /the quick brown fox/I the quick brown fox this is a line with the quick brown fox /the quick brown fox/IA the quick brown fox *** Failers this is a line with the quick brown fox /ab(?z)cd/ /^abc|def/I abcdef abcdef\B /.*((abc)$|(def))/I defabc \Zdefabc /)/ /a[]b/ /[^aeiou ]{3,}/I co-processors, and for /<.*>/I abcghinop /<.*?>/I abcghinop /<.*>/IU abcghinop /(?U)<.*>/I abcghinop /<.*?>/IU abcghinop /={3,}/IU abc========def /(?U)={3,}?/I abc========def /(?^abc)/Im abc def\nabc *** Failers defabc /(?<=ab(c+)d)ef/ /(?<=ab(?<=c+)d)ef/ /(?<=ab(c|de)f)g/ /The next three are in testinput2 because they have variable length branches/ /(?<=bullock|donkey)-cart/I the bullock-cart a donkey-cart race *** Failers cart horse-and-cart /(?<=ab(?i)x|y|z)/I /(?>.*)(?<=(abcd)|(xyz))/I alphabetabcd endingxyz /(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/I abxyZZ abXyZZ ZZZ zZZ bZZ BZZ *** Failers ZZ abXYZZ zzz bzz /(?[^()]+) # Either a sequence of non-brackets (no backtracking) | # Or (?R) # Recurse - i.e. nested bracketed string )* # Zero or more contents \) # Closing ) /Ix (abcd) (abcd)xyz xyz(abcd) (ab(xy)cd)pqr (ab(xycd)pqr () abc () 12(abcde(fsh)xyz(foo(bar))lmno)89 *** Failers abcd abcd) (abcd /\( ( (?>[^()]+) | (?R) )* \) /Ixg (ab(xy)cd)pqr 1(abcd)(x(y)z)pqr /\( (?: (?>[^()]+) | (?R) ) \) /Ix (abcd) (ab(xy)cd) (a(b(c)d)e) ((ab)) *** Failers () /\( (?: (?>[^()]+) | (?R) )? \) /Ix () 12(abcde(fsh)xyz(foo(bar))lmno)89 /\( ( (?>[^()]+) | (?R) )* \) /Ix (ab(xy)cd) /\( ( ( (?>[^()]+) | (?R) )* ) \) /Ix (ab(xy)cd) /\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /Ix (ab(xy)cd) (123ab(xy)cd) /\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /Ix (ab(xy)cd) (123ab(xy)cd) /\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /Ix (ab(xy)cd) /\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /Ix (abcd(xyz

\n" if ($inpre); print TEMP "

\n"; } $inpara = $inpre = 0; $wrotetext = 0; } # Subroutine to start a new paragraph sub new_para { &end_para(); print TEMP "

\n"; $inpara = 1; } # Main program $innf = 0; $inpara = 0; $inpre = 0; $wrotetext = 0; $toc = 0; $ref = 1; while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) { $toc = 1 if $ARGV[0] eq "-toc"; shift; } # Initial output to STDOUT print < $ARGV[0] specification

$ARGV[0] man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.
End print "

    \n" if ($toc); open(TEMP, ">/tmp/$$") || die "Can't open /tmp/$$ for output\n"; while () { # Handle lines beginning with a dot if (/^\./) { # Some of the PCRE man pages used to contain instances of .br. However, # they should have all been removed because they cause trouble in some # (other) automated systems that translate man pages to HTML. Complain if # we find .br or .in (another macro that is deprecated). if (/^\.br/ || /^\.in/) { print STDERR "\n*** Deprecated macro encountered - rewrite needed\n"; print STDERR "*** $_\n"; die "*** Processing abandoned\n"; } # Instead of .br, relevent "literal" sections are enclosed in .nf/.fi. elsif (/^\.nf/) { $innf = 1; } elsif (/^\.fi/) { $innf = 0; } # Handling .sp is subtle. If it is inside a literal section, do nothing if # the next line is a non literal text line; similarly, if not inside a # literal section, do nothing if a literal follows. The point being that # the
     and 
    that delimit literal sections will do the spacing. # Always skip if no previous output. elsif (/^\.sp/) { if ($wrotetext) { $_ = ; if ($inpre) { print TEMP "\n" if (/^[\s.]/); } else { print TEMP "
    \n
    \n" if (!/^[\s.]/); } redo; # Now process the lookahead line we just read } } elsif (/^\.TP/ || /^\.PP/ || /^\.P/) { &new_para(); } elsif (/^\.SH\s*("?)(.*)\1/) { # Ignore the NAME section if ($2 =~ /^NAME\b/) { ; next; } &end_para(); my($title) = &do_line($2); if ($toc) { printf("
  • $title\n", $ref, $ref); printf TEMP ("
    $title
    \n", $ref, $ref); $ref++; } else { print TEMP "
    \n$title\n
    \n"; } } elsif (/^\.SS\s*("?)(.*)\1/) { &end_para(); my($title) = &do_line($2); print TEMP "
    \n$title\n
    \n"; } elsif (/^\.B\s*(.*)/) { &new_para() if (!$inpara); $_ = &do_line($1); s/"(.*?)"/$1/g; print TEMP "$_\n"; $wrotetext = 1; } elsif (/^\.I\s*(.*)/) { &new_para() if (!$inpara); $_ = &do_line($1); s/"(.*?)"/$1/g; print TEMP "$_\n"; $wrotetext = 1; } # A comment that starts "HREF" takes the next line as a name that # is turned into a hyperlink, using the text given, which might be # in a special font. If it ends in () or (digits) or punctuation, they # aren't part of the link. elsif (/^\.\\"\s*HREF/) { $_=; chomp; $_ = &do_line($_); $_ =~ s/\s+$//; $_ =~ /^(?:<.>)?([^<(]+)(?:\(\))?(?:<\/.>)?(?:\(\d+\))?[.,;:]?$/; print TEMP "$_\n"; } # A comment that starts "HTML" inserts literal HTML elsif (/^\.\\"\s*HTML\s*(.*)/) { print TEMP $1; } # A comment that starts < inserts that HTML at the end of the # *next* input line - so as not to get a newline between them. elsif (/^\.\\"\s*(<.*>)/) { my($markup) = $1; $_=; chomp; $_ = &do_line($_); $_ =~ s/\s+$//; print TEMP "$_$markup\n"; } # A comment that starts JOIN joins the next two lines together, with one # space between them. Then that line is processed. This is used in some # displays where two lines are needed for the "man" version. JOINSH works # the same, except that it assumes this is a shell command, so removes # continuation backslashes. elsif (/^\.\\"\s*JOIN(SH)?/) { my($one,$two); $one = ; $two = ; $one =~ s/\s*\\e\s*$// if (defined($1)); chomp($one); $two =~ s/^\s+//; $_ = "$one $two"; redo; # Process the joined lines } # .EX/.EE are used in the pcredemo page to bracket the entire program, # which is unmodified except for turning backslash into "\e". elsif (/^\.EX\s*$/) { print TEMP "
    \n";
          while ()
            {
            last if /^\.EE\s*$/;
            s/\\e/\\/g;
            s/&/&/g;
            s//>/g;
            print TEMP;
            }
          }
    
        # Ignore anything not recognized
    
        next;
        }
    
      # Line does not begin with a dot. Replace blank lines with new paragraphs
    
      if (/^\s*$/)
        {
        &end_para() if ($wrotetext);
        next;
        }
    
      # Convert fonts changes and output an ordinary line. Ensure that indented
      # lines are marked as literal.
    
      $_ = &do_line($_);
      &new_para() if (!$inpara);
    
      if (/^\s/)
        {
        if (!$inpre)
          {
          print TEMP "
    \n";
          $inpre = 1;
          }
        }
      elsif ($inpre)
        {
        print TEMP "
    \n"; $inpre = 0; } # Add
    to the end of a non-literal line if we are within .nf/.fi $_ .= "
    \n" if (!$inpre && $innf); print TEMP; $wrotetext = 1; } # The TOC, if present, will have been written - terminate it print "
\n" if ($toc); # Copy the remainder to the standard output close(TEMP); open(TEMP, "/tmp/$$") || die "Can't open /tmp/$$ for input\n"; print while (); print < Return to the PCRE index page.

End close(TEMP); unlink("/tmp/$$"); # End pcre-8.31/pcre16_utf16_utils.c0000644000222100022210000001140611703042632013014 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains a function for converting any UTF-16 character strings to host byte order. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_internal.h" /************************************************* * Convert any UTF-16 string to host byte order * *************************************************/ /* This function takes an UTF-16 string and converts it to host byte order. The length can be explicitly set, or automatically detected for zero terminated strings. BOMs can be kept or discarded during the conversion. Conversion can be done in place (output == input). Arguments: output the output buffer, its size must be greater or equal than the input string input any UTF-16 string length the number of 16-bit units in the input string can be less than zero for zero terminated strings host_byte_order A non-zero value means the input is in host byte order, which can be dynamically changed by BOMs later. Initially it contains the starting byte order and returns with the last byte order so it can be used for stream processing. It can be NULL, which set the host byte order mode by default. keep_boms for a non-zero value, the BOM (0xfeff) characters are copied as well Returns: the number of 16-bit units placed into the output buffer, including the zero-terminator */ int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input, int length, int *host_byte_order, int keep_boms) { #ifdef SUPPORT_UTF /* This function converts any UTF-16 string to host byte order and optionally removes any Byte Order Marks (BOMS). Returns with the remainig length. */ int host_bo = host_byte_order != NULL ? *host_byte_order : 1; pcre_uchar *optr = (pcre_uchar *)output; const pcre_uchar *iptr = (const pcre_uchar *)input; const pcre_uchar *end; /* The c variable must be unsigned. */ register pcre_uchar c; if (length < 0) length = STRLEN_UC(iptr) + 1; end = iptr + length; while (iptr < end) { c = *iptr++; if (c == 0xfeff || c == 0xfffe) { /* Detecting the byte order of the machine is unnecessary, it is enough to know that the UTF-16 string has the same byte order or not. */ host_bo = c == 0xfeff; if (keep_boms != 0) *optr++ = 0xfeff; else length--; } else *optr++ = host_bo ? c : ((c >> 8) | (c << 8)); /* Flip bytes if needed. */ } if (host_byte_order != NULL) *host_byte_order = host_bo; #else /* SUPPORT_UTF */ (void)(output); /* Keep picky compilers happy */ (void)(input); (void)(keep_boms); #endif /* SUPPORT_UTF */ return length; } /* End of pcre16_utf16_utils.c */ pcre-8.31/libpcreposix.pc.in0000644000222100022210000000051211247245107012740 00000000000000# Package Information for pkg-config prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpcreposix Description: PCREPosix - Posix compatible interface to libpcre Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpcreposix Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ Requires.private: libpcre pcre-8.31/COPYING0000644000222100022210000000013710602702230010327 00000000000000PCRE LICENCE Please see the file LICENCE in the PCRE distribution for licensing details. End pcre-8.31/pcre_fullinfo.c0000644000222100022210000001501011762370424012301 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_fullinfo(), which returns information about a compiled pattern. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Return info about compiled pattern * *************************************************/ /* This is a newer "info" function which has an extensible interface so that additional items can be added compatibly. Arguments: argument_re points to compiled code extra_data points extra data, or NULL what what information is required where where to put the information Returns: 0 if data returned, negative on error */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what, void *where) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data, int what, void *where) #endif { const REAL_PCRE *re = (const REAL_PCRE *)argument_re; const pcre_study_data *study = NULL; if (re == NULL || where == NULL) return PCRE_ERROR_NULL; if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; /* Check that the first field in the block is the magic number. If it is not, return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which means that the pattern is likely compiled with different endianness. */ if (re->magic_number != MAGIC_NUMBER) return re->magic_number == REVERSED_MAGIC_NUMBER? PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; /* Check that this pattern was compiled in the correct bit mode */ if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; switch (what) { case PCRE_INFO_OPTIONS: *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS; break; case PCRE_INFO_SIZE: *((size_t *)where) = re->size; break; case PCRE_INFO_STUDYSIZE: *((size_t *)where) = (study == NULL)? 0 : study->size; break; case PCRE_INFO_JITSIZE: #ifdef SUPPORT_JIT *((size_t *)where) = (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra_data->executable_jit != NULL)? PRIV(jit_get_size)(extra_data->executable_jit) : 0; #else *((size_t *)where) = 0; #endif break; case PCRE_INFO_CAPTURECOUNT: *((int *)where) = re->top_bracket; break; case PCRE_INFO_BACKREFMAX: *((int *)where) = re->top_backref; break; case PCRE_INFO_FIRSTBYTE: *((int *)where) = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char : ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; break; /* Make sure we pass back the pointer to the bit vector in the external block, not the internal copy (with flipped integer fields). */ case PCRE_INFO_FIRSTTABLE: *((const pcre_uint8 **)where) = (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)? ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; break; case PCRE_INFO_MINLENGTH: *((int *)where) = (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)? (int)(study->minlength) : -1; break; case PCRE_INFO_JIT: *((int *)where) = extra_data != NULL && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra_data->executable_jit != NULL; break; case PCRE_INFO_LASTLITERAL: *((int *)where) = ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1; break; case PCRE_INFO_NAMEENTRYSIZE: *((int *)where) = re->name_entry_size; break; case PCRE_INFO_NAMECOUNT: *((int *)where) = re->name_count; break; case PCRE_INFO_NAMETABLE: *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset; break; case PCRE_INFO_DEFAULT_TABLES: *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables)); break; /* From release 8.00 this will always return TRUE because NOPARTIAL is no longer ever set (the restrictions have been removed). */ case PCRE_INFO_OKPARTIAL: *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0; break; case PCRE_INFO_JCHANGED: *((int *)where) = (re->flags & PCRE_JCHANGED) != 0; break; case PCRE_INFO_HASCRORLF: *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0; break; case PCRE_INFO_MAXLOOKBEHIND: *((int *)where) = re->max_lookbehind; break; default: return PCRE_ERROR_BADOPTION; } return 0; } /* End of pcre_fullinfo.c */ pcre-8.31/pcre-config.in0000644000222100022210000000431711706560434012042 00000000000000#!/bin/sh prefix=@prefix@ exec_prefix=@exec_prefix@ exec_prefix_set=no cflags="[--cflags]" if test @enable_cpp@ = yes ; then libs="[--libs-cpp]" else libs= fi if test @enable_pcre16@ = yes ; then libs="[--libs16] $libs" fi if test @enable_pcre8@ = yes ; then libs="[--libs] [--libs-posix] $libs" cflags="$cflags [--cflags-posix]" fi usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] $libs $cflags" if test $# -eq 0; then echo "${usage}" 1>&2 exit 1 fi libR= case `uname -s` in *SunOS*) libR=" -R@libdir@" ;; *BSD*) libR=" -Wl,-R@libdir@" ;; esac libS= if test @libdir@ != /usr/lib ; then libS=-L@libdir@ fi while test $# -gt 0; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case $1 in --prefix=*) prefix=$optarg if test $exec_prefix_set = no ; then exec_prefix=$optarg fi ;; --prefix) echo $prefix ;; --exec-prefix=*) exec_prefix=$optarg exec_prefix_set=yes ;; --exec-prefix) echo $exec_prefix ;; --version) echo @PACKAGE_VERSION@ ;; --cflags) if test @includedir@ != /usr/include ; then includes=-I@includedir@ fi echo $includes @PCRE_STATIC_CFLAG@ ;; --cflags-posix) if test @enable_pcre8@ = yes ; then if test @includedir@ != /usr/include ; then includes=-I@includedir@ fi echo $includes @PCRE_STATIC_CFLAG@ else echo "${usage}" 1>&2 fi ;; --libs-posix) if test @enable_pcre8@ = yes ; then echo $libS$libR -lpcreposix -lpcre else echo "${usage}" 1>&2 fi ;; --libs) if test @enable_pcre8@ = yes ; then echo $libS$libR -lpcre else echo "${usage}" 1>&2 fi ;; --libs16) if test @enable_pcre16@ = yes ; then echo $libS$libR -lpcre16 else echo "${usage}" 1>&2 fi ;; --libs-cpp) if test @enable_cpp@ = yes ; then echo $libS$libR -lpcrecpp -lpcre else echo "${usage}" 1>&2 fi ;; *) echo "${usage}" 1>&2 exit 1 ;; esac shift done pcre-8.31/pcre16_ord2utf16.c0000644000222100022210000000656211676645212012406 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This file contains a private PCRE function that converts an ordinal character value into a UTF16 string. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_internal.h" /************************************************* * Convert character value to UTF-16 * *************************************************/ /* This function takes an integer value in the range 0 - 0x10ffff and encodes it as a UTF-16 character in 1 to 2 pcre_uchars. Arguments: cvalue the character value buffer pointer to buffer for result - at least 2 pcre_uchars long Returns: number of characters placed in the buffer */ int PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) { #ifdef SUPPORT_UTF /* Checking invalid cvalue character, encoded as invalid UTF-16 character. Should never happen in practice. */ if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000) cvalue = 0xfffe; if (cvalue <= 0xffff) { *buffer = (pcre_uchar)cvalue; return 1; } cvalue -= 0x10000; *buffer++ = 0xd800 | (cvalue >> 10); *buffer = 0xdc00 | (cvalue & 0x3ff); return 2; #else /* SUPPORT_UTF */ (void)(cvalue); /* Keep compiler happy; this function won't ever be */ (void)(buffer); /* called when SUPPORT_UTF is not defined. */ return 0; #endif /* SUPPORT_UTF */ } /* End of pcre16_ord2utf16.c */ pcre-8.31/pcre_chartables.c.dist0000644000222100022210000001725011676645227013557 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This file contains character tables that are used when no external tables are passed to PCRE by the application that calls it. The tables are used only for characters whose code values are less than 256. This is a default version of the tables that assumes ASCII encoding. A program called dftables (which is distributed with PCRE) can be used to build alternative versions of this file. This is necessary if you are running in an EBCDIC environment, or if you want to default to a different encoding, for example ISO-8859-1. When dftables is run, it creates these tables in the current locale. If PCRE is configured with --enable-rebuild-chartables, this happens automatically. The following #includes are present because without them gcc 4.x may remove the array definition from the final binary if PCRE is built into a static library and dead code stripping is activated. This leads to link errors. Pulling in the header ensures that the array gets flagged as "someone outside this compilation unit might reference this" and so it will always be supplied to the linker. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" const pcre_uint8 PRIV(default_tables)[] = { /* This table is a lower casing table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table is a case flipping table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table contains bit maps for various character classes. Each map is 32 bytes long and the bits run from the least significant end of each byte. The classes that have their own maps are: space, xdigit, digit, upper, lower, word, graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* This table identifies various classes of character by individual bits: 0x01 white space character 0x02 letter 0x04 decimal digit 0x08 hexadecimal digit 0x10 alphanumeric or '_' 0x80 regular expression metacharacter or binary zero */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ /* End of pcre_chartables.c */ pcre-8.31/pcre16_dfa_exec.c0000644000222100022210000000420311676645212012376 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Generate code with 16 bit character support. */ #define COMPILE_PCRE16 #include "pcre_dfa_exec.c" /* End of pcre16_dfa_exec.c */ pcre-8.31/pcre_refcount.c0000644000222100022210000000706111701567032012313 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_refcount(), which is an auxiliary function that can be used to maintain a reference count in a compiled pattern data block. This might be helpful in applications where the block is shared by different users. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pcre_internal.h" /************************************************* * Maintain reference count * *************************************************/ /* The reference count is a 16-bit field, initialized to zero. It is not possible to transfer a non-zero count from one host to a different host that has a different byte order - though I can't see why anyone in their right mind would ever want to do that! Arguments: argument_re points to compiled code adjust value to add to the count Returns: the (possibly updated) count value (a non-negative number), or a negative error number */ #ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_refcount(pcre *argument_re, int adjust) #else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_refcount(pcre16 *argument_re, int adjust) #endif { REAL_PCRE *re = (REAL_PCRE *)argument_re; if (re == NULL) return PCRE_ERROR_NULL; if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; re->ref_count = (-adjust > re->ref_count)? 0 : (adjust + re->ref_count > 65535)? 65535 : re->ref_count + adjust; return re->ref_count; } /* End of pcre_refcount.c */